WinForms FAQ - ComboBox

Find answers for the most frequently asked questions
Expand All Collapse All

You can subclass ComboBox. In your derived class, make sure you set

  this.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
  this.DropDownStyle = ComboBoxStyle.DropDownList;

You also need to handle the DrawItem event to actually implement the drawing. Check out the details in the OwnerDrawnComboBox sample.

Permalink

This entry was created using the feedback provided by Jay Harlow in the newsgroups.

The enum values can be bound to a combobox as follows:


[C#]
// Setup the binding as follows:
// MyValues is the enum type
comboBox1.DataSource = Enum.GetValues(typeof MyValues);
[VB]
comboBox1.DataSource = Enum.GetValues(Type.GetType(MyValues))

Then in the SelectedValueChanged event for the ComboBox.


[C#]
private void ComboBox1ValueChanged(object sender, EventArgs e)
{
    MyValues v = (MyValues)this.comboBox1.SelectedValue;
}
[VB]
Private  Sub ComboBox1ValueChanged(ByVal sender As Object, ByVal e As EventArgs)
    Dim v As MyValues = CType(Me.comboBox1.SelectedValue, MyValues)
End Sub
Permalink

Here are some snippets. (Courtesy of Michael Lang)

[C#]
	DataTable list = new DataTable();
	list.Columns.Add(new DataColumn('Display', typeof(string)));
	list.Columns.Add(new DataColumn('Id', typeof(int)));
	list.Rows.Add(list.NewRow());
	list.Rows.Add(list.NewRow());
	list.Rows.Add(list.NewRow());
	list.Rows[0][0] = 'one';
	list.Rows[0][1] = 1;
	list.Rows[1][0] = 'two';
	list.Rows[1][1] = 2;
	list.Rows[2][0] = 'three';
	list.Rows[2][1] = 3;
	comboBox1.DataSource = list;
	comboBox1.DisplayMember = 'Display';
	comboBox1.ValueMember = 'Id';

[VB.NET]
	Dim list As New DataTable()
	list.Columns.Add(New DataColumn('Display', GetType(String)))
	list.Columns.Add(New DataColumn('Id', GetType(Integer)))
	list.Rows.Add(list.NewRow())
	list.Rows.Add(list.NewRow())
	list.Rows.Add(list.NewRow())
	list.Rows(0)(0) = 'one' ’
	list.Rows(0)(1) = 1 ’
	list.Rows(1)(0) = 'two' ’
	list.Rows(1)(1) = 2 ’
	list.Rows(2)(0) = 'three' ’
	list.Rows(2)(1) = 3 ’
	comboBox1.DataSource = list
	comboBox1.DisplayMember = 'Display'
	comboBox1.ValueMember = 'Id'
Permalink

You can avoid the combobox dropping by overriding its WndProc method and ignoring the WM_LBUTTONDOWN and WM_LBUTTONDBLCLK.

[C#]
 public class MyComboBox : ComboBox
 {
	protected override void WndProc(ref System.Windows.Forms.Message m)
	{
		 if(m.Msg == 0x201  //WM_LBUTTONDOWN
		    || m.Msg == 0x203)  //WM_LBUTTONDBLCLK
  			 return;
		base.WndProc(ref m);
	}
 }

[VB.NET]
Public Class MyComboBox
	Inherits ComboBox
   
	Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
		If m.Msg = &H201 OrElse m.Msg = &H203 Then ’WM_LBUTTONDOWN  or WM_LBUTTONDBLCLK
			Return
		End If

		MyBase.WndProc(m)
	End Sub ’WndProc
End Class ’MyComboBox
Permalink

You can iterate through the list to find the longest text extent using MeasureString, and then use this as the combobox width adding a fudge factor for the dropdown button.

	System.Drawing.Graphics g = comboBox1.CreateGraphics();
	float maxWidth = 0f;
	foreach(object o in comboBox1.Items)
	{
		float w = g.MeasureString(o.ToString(), comboBox1.Font).Width;
		if(w > maxWidth)
			maxWidth = w;
	}
	g.Dispose();
	comboBox1.Width = (int) maxWidth + 20; // 20 is to take care of button width
Permalink

Share with

Couldn't find the FAQs you're looking for?

Please submit your question and answer.