I would like to resize any ComboBox
dropdown width based on the longest string in the dropdown items. I want this to work on any ComboBox
with items which means one whose items are strings, some object with DisplayMember
set, or a DataTable
. I found some code which works for strings, but not when a DisplayMember
is set
static void resizeCombo(ComboBox cb)
{
cb.DropDownWidth = cb.Items.Cast<string>().Max(x => TextRenderer.MeasureText(x, cb.Font).Width);
}
In the following three examples, the first which is just strings will work, but the following two don't work (cb.Items.Cast<string>()
cast to string fails), and demonstrate that the DisplayMember can vary when bound to sources of different classes, so I can't just use "Name" for example
var c = new string[] { "Name1", "Name2" };
comboBox.DataSource = c.ToList();
resizeCombo(comboBox);
var c1 = new Class1[] { new Class1() { ID = 1, Name1 = "Name1" }, new Class1() { ID = 2, Name1 = "Name2" } };
comboBox1.DisplayMember = "Name1";
comboBox1.ValueMember = "ID";
comboBox1.DataSource = c1.ToList();
resizeCombo(comboBox1);
var c2 = new Class2[] { new Class2() { ID = 2, Name2 = "Name1" }, new Class2() { ID = 2, Name2 = "Name2" } };
comboBox2.DisplayMember = "Name2";
comboBox2.ValueMember = "ID";
comboBox2.DataSource = c2.ToList();
resizeCombo(comboBox2);
I could reflect the DisplayMember
, and find the strings by name, and it may solve the List<class>
case, but not DataTable
.
I am looking for a method to get all the strings in the ComboBox
regardless of how they are added. Is there one?
CodePudding user response:
Combobox has GetItemText
method that returns the string representation of item.
This should work:
static void resizeCombo(ComboBox cb)
{
if (cb.Items.Count == 0) cb.DropDownWidth = cb.Width;
else
{
int maxWidth = int.MinValue;
for (int i = 0; i < cb.Items.Count; i )
{
maxWidth = Math.Max(maxWidth, TextRenderer.MeasureText(cb.GetItemText(cb.Items[i]), cb.Font).Width);
}
if (cb.Items.Count > cb.MaxDropDownItems) maxWidth = SystemInformation.VerticalScrollBarWidth
cb.DropDownWidth = maxWidth;
}
}
To test with DataTable:
DataTable t = new DataTable();
t.Columns.Add(new DataColumn("ID", typeof(int)));
t.Columns.Add(new DataColumn("Name2", typeof(string)));
t.Rows.Add(new object[] { 1, "Somename" });
t.Rows.Add(new object[] { 2, "Some other name" });
comboBox2.DisplayMember = "Name2";
comboBox2.ValueMember = "ID";
comboBox2.DataSource = t;
resizeCombo(comboBox2);
NB! For this to work, do not use the resize function in a form's constructor. Use it from the Load event or similar, once the form is already up and running.