DataSourceとDisplayMemberから文字列を取得して描画するサンプル。
DataSourceを使っても、Items.Addを使ってもうまくいくようになってます。
以前、わんくまBBSで教えてもらったんですが、ログが残ってないのでここにメモっときます。
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
namespace ODCTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PropertyInfo[] props = typeof( Color ).GetProperties( BindingFlags.Public | BindingFlags.Static );
foreach( PropertyInfo prop in props )
{
if( prop.PropertyType != typeof( Color ) )
{
continue;
}
Color color = ( Color )prop.GetValue( null, null );
if( color == Color.Transparent )
{
continue;
}
this.comboBox1.Items.Add( color );
}
this.comboBox1.SelectedIndex = 0;
}
private void ComboBox_DrawItem( object sender, DrawItemEventArgs e )
{
ComboBox target = ( ComboBox )sender;
Color backColor = e.BackColor;
if( ( e.State & DrawItemState.Disabled ) != 0 )
{
backColor = SystemColors.Control;
}
else if( e.Index != -1 )
{
backColor = ( Color )target.Items[ e.Index ];
}
Size halfRectSize = new Size( e.Bounds.Width / 2, e.Bounds.Height );
Rectangle textRect = new Rectangle(
new Point( e.Bounds.Left, e.Bounds.Top ), halfRectSize );
Rectangle colorRect = new Rectangle(
new Point( e.Bounds.Left + halfRectSize.Width, e.Bounds.Top ), halfRectSize );
using( SolidBrush backBrush = new SolidBrush( backColor ) )
{
e.Graphics.FillRectangle( backBrush, colorRect );
}
if( e.Index != -1 )
{
object item = target.Items[ e.Index ];
object dispObject = item;
if( target.DataSource != null )
{
BindingManagerBase bmb = target.BindingContext[ target.DataSource ];
PropertyDescriptorCollection properties = bmb.GetItemProperties();
PropertyDescriptor dispProp = properties[ target.DisplayMember ];
if( dispProp != null )
{
dispObject = dispProp.GetValue( item );
}
}
string itemText = TypeDescriptor.GetConverter( dispObject ).ConvertToString( dispObject );
StringFormat sf = ( StringFormat )StringFormat.GenericDefault.Clone();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
Color foreColor = e.ForeColor;
if( ( e.State & DrawItemState.Disabled ) != 0 )
{
foreColor = SystemColors.GrayText;
}
else
{
foreColor = SystemColors.ControlText;
}
e.Graphics.FillRectangle( SystemBrushes.Window, textRect );
using( SolidBrush foreBrush = new SolidBrush( foreColor ) )
{
e.Graphics.DrawString( itemText, e.Font, foreBrush, textRect, sf );
}
}
if( ( e.State & DrawItemState.Focus ) != 0 )
{
e.DrawFocusRectangle();
}
}
}
}