问题
Does anybody know a way to set the ComboBox's content's width to autosize
I do not mean the ComboBox itself, just the opened content.
回答1:
You can't use it directly.
Do a trick
First iterate through all items of your combobox, check for the width of every items by assigning the text to a label. Then, check width every time, if width of current item gets greater than previous items then change the maximum width.
int DropDownWidth(ComboBox myCombo)
{
int maxWidth = 0;
int temp = 0;
Label label1 = new Label();
foreach (var obj in myCombo.Items)
{
label1.Text = obj.ToString();
temp = label1.PreferredWidth;
if (temp > maxWidth)
{
maxWidth = temp;
}
}
label1.Dispose();
return maxWidth;
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.DropDownWidth = DropDownWidth(comboBox1);
}
OR
As suggested by stakx, you can use TextRenderer class
int DropDownWidth(ComboBox myCombo)
{
int maxWidth = 0, temp = 0;
foreach (var obj in myCombo.Items)
{
temp = TextRenderer.MeasureText(obj.ToString(), myCombo.Font).Width;
if (temp > maxWidth)
{
maxWidth = temp;
}
}
return maxWidth;
}
回答2:
Here is very elegant solution. Just subscribe your combobox to this event handler:
private void AdjustWidthComboBox_DropDown(object sender, EventArgs e)
{
var senderComboBox = (ComboBox)sender;
int width = senderComboBox.DropDownWidth;
Graphics g = senderComboBox.CreateGraphics();
Font font = senderComboBox.Font;
int vertScrollBarWidth = (senderComboBox.Items.Count > senderComboBox.MaxDropDownItems)
? SystemInformation.VerticalScrollBarWidth : 0;
var itemsList = senderComboBox.Items.Cast<object>().Select(item => item.ToString());
foreach (string s in itemsList)
{
int newWidth = (int)g.MeasureString(s, font).Width + vertScrollBarWidth;
if (width < newWidth)
{
width = newWidth;
}
}
senderComboBox.DropDownWidth = width;
}
This code was taken from the codeproject: Adjust combo box drop down list width to longest string width. But I have modified it to work with comboboxes filled with any data (not only strings).
回答3:
obj.ToString() doesn't work for me, I suggest to use myCombo.GetItemText(obj). This works for me:
private int DropDownWidth(ComboBox myCombo)
{
int maxWidth = 0, temp = 0;
foreach (var obj in myCombo.Items)
{
temp = TextRenderer.MeasureText(myCombo.GetItemText(obj), myCombo.Font).Width;
if (temp > maxWidth)
{
maxWidth = temp;
}
}
return maxWidth + SystemInformation.VerticalScrollBarWidth;
}
回答4:
Mostly the same code as in Javed Akram's second suggestion, but the width of the vertical scroll bar is added:
int setWidth_comboBox(ComboBox cb)
{
int maxWidth = 0, temp = 0;
foreach (string s in cb.Items)
{
temp = TextRenderer.MeasureText(s, cb.Font).Width;
if (temp > maxWidth)
{
maxWidth = temp;
}
}
return maxWidth + SystemInformation.VerticalScrollBarWidth;
}
Use the code like this (on a form with a combobox with the name myComboBox):
myComboBox.Width = setWidth_comboBox(myComboBox);
回答5:
This is an old question, but I just ran into it and combined a couple of the answers for my solution. I liked the simplicity of the accepted answer but wanted something that would work with any object type in the combo box. I also wanted to make use of the method through an extension method.
public static int AutoDropDownWidth(this ComboBox myCombo)
{
return AutoDropDownWidth<object>(myCombo, o => o.ToString());
}
public static int AutoDropDownWidth<T>(this ComboBox myCombo, Func<T, string> description)
{
int maxWidth = 1;
int temp = 1;
int vertScrollBarWidth = (myCombo.Items.Count > myCombo.MaxDropDownItems)
? SystemInformation.VerticalScrollBarWidth : 0;
foreach (T obj in myCombo.Items)
{
if (obj is T)
{
T t = (T)obj;
temp = TextRenderer.MeasureText(description(t), myCombo.Font).Width;
if (temp > maxWidth)
{
maxWidth = temp;
}
}
}
return maxWidth + vertScrollBarWidth;
}
This way if my class is:
public class Person
{
public string FullName {get;set;}
}
I could auto adjust the combo box drop down width like this:
cbPeople.DropDownWidth = cbPeople.AutoDropDownWidth<Person>(p => p.FullName);
回答6:
Old but classic, hope to work fast enough
private int GetDropDownWidth(ComboBox combo)
{
object[] items = new object[combo.Items.Count];
combo.Items.CopyTo(items, 0);
return items.Select(obj => TextRenderer.MeasureText(combo.GetItemText(obj), combo.Font).Width).Max();
}
回答7:
Vote for algreat's answer below.
I simply modified algreat's answer with code resize the entire control.
I would have just added it as a comment but couldn't add formatted code on the comment.
private void combo_DropDown(object sender, EventArgs e)
{
//http://www.codeproject.com/Articles/5801/Adjust-combo-box-drop-down-list-width-to-longest-s
ComboBox senderComboBox = (ComboBox)sender;
int width = senderComboBox.DropDownWidth;
Graphics g = senderComboBox.CreateGraphics();
Font font = senderComboBox.Font;
int vertScrollBarWidth =
(senderComboBox.Items.Count > senderComboBox.MaxDropDownItems)
? SystemInformation.VerticalScrollBarWidth : 0;
int newWidth;
foreach (string s in ((ComboBox)sender).Items)
{
newWidth = (int)g.MeasureString(s, font).Width
+ vertScrollBarWidth;
if (width < newWidth)
{
width = newWidth;
}
if (senderComboBox.Width < newWidth)
{
senderComboBox.Width = newWidth+ SystemInformation.VerticalScrollBarWidth;
}
}
senderComboBox.DropDownWidth = width;
}
来源:https://stackoverflow.com/questions/4842160/auto-width-of-comboboxs-content