有人知道如何将
ComboBox
下拉的内容宽度设置为自适应大小吗?我指的不是ComboBox
本身,而是打开的内容。你不能直接使用它。
进行小技巧
首先遍历下拉框的所有项,通过将文本赋值给标签来检查每个项的宽度。然后每次检查宽度时,如果当前项的宽度大于之前的项,则更改最大宽度。
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);
}
或者
如stakx所建议的,你可以使用TextRenderer
类。
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;
}
obj.ToString() 对我无效,建议使用 myCombo.GetItemText(obj)。这对我有效:
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;
}
myCombo.GetItemText(obj)
绝对比其他答案更正确。obj.ToString()
可能与组合框的DisplayMember
属性不同。 - Russell Trahan这里有一个非常优雅的解决方案。只需将您的组合框订阅到此事件处理程序即可:
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;
}
这段代码来自codeproject:调整组合框下拉列表宽度以适应最长字符串宽度。 但我已经修改它可以与任何数据(不仅仅是字符串)填充的组合框一起使用。
Graphics
实例后,应该立即将其处理掉,最好的方法是将其包装在using
块中以进行自动释放。 - vgruprivate 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;
}
这段代码与Javed Akram的第二个建议基本相同,只是加入了垂直滚动条的宽度:
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;
}
使用以下代码(在具有名称为myComboBox的组合框的表单上):
myComboBox.Width = setWidth_comboBox(myComboBox);
旧但经典,希望能够快速运作
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();
}
private int AutoSizeDropDownWidth(ComboBox comboBox)
{
var width = cmboxUnit.DropDownWidth;
var g = cmboxUnit.CreateGraphics();
var font = cmboxUnit.Font;
var verticalScrollBarWidth = cmboxUnit.Items.Count > cmboxUnit.MaxDropDownItems
? SystemInformation.VerticalScrollBarWidth : 0;
var itemsList = cmboxUnit.Items.Cast<object>().Select(item => item);
foreach (DataRowView dr in itemsList)
{
int newWidth = (int)g.MeasureString(dr["Name"].ToString(), font).Width + verticalScrollBarWidth;
if (width < newWidth)
{
width = newWidth;
}
}
return width;
}
此答案基于@user2361362的回答。代码使用LINQ进行修改,并转换为一个函数,该函数可设置给定ComboBox的下拉框宽度:
private void SetComboBoxDropDownWidth(ComboBox comboBox)
{
var width = (from object obj in comboBox.Items
select TextRenderer.MeasureText(comboBox.GetItemText(obj), comboBox.Font).Width)
.Prepend(0)
.Max();
comboBox.DropDownWidth = width + SystemInformation.VerticalScrollBarWidth;
}
这是一个老问题,但我刚遇到它,并结合了几个答案来解决它。我喜欢被接受的答案的简单性,但希望有些东西可以与组合框中的任何对象类型一起使用。我还想通过扩展方法利用该方法。
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;
}
如果我的类是这样的:
public class Person
{
public string FullName {get;set;}
}
cbPeople.DropDownWidth = cbPeople.AutoDropDownWidth<Person>(p => p.FullName);
TComboBox.ItemWidth是您要查找的属性。它具有您想要的行为,而无需任何编码。只需在设计时或以编程方式将其设置为比Width大的某些值,当用户下拉框时,他们将获得更宽的选择列表。
TComboBox
?您所说的ItemWidth
属性是什么?https://learn.microsoft.com/en-us/search/?scope=.NET&terms=combobox%20itemwidth 没有任何结果。 - Peter Duniho
label1.PreferredWidth
的技巧表现良好时,一个稍微更直接和"表达性"更强的测量文本宽度的方法是使用TextRenderer.MeasureText
...? - stakx - no longer contributingcomboBox1.DropDownWidth = comboBox1.Items.Cast<string>().Max(x => TextRenderer.MeasureText(x, comboBox1.Font).Width);
,它可以让下拉框的宽度适应其最长选项的长度。 - Andyobj.ToString()
可能与组合框的DisplayMember
属性不同。myCombo.GetItemText(obj)
明显比其他答案更正确。 - Russell TrahanGetItemText
的一行代码:comboBox1.DropDownWidth = comboBox1.Items.Cast<object>().Max(o => TextRenderer.MeasureText(comboBox1.GetItemText(o), comboBox1.Font).Width);
注:这段代码会根据下拉框内的选项长度自动调整下拉框的宽度。 - Alain