简体   繁体   English

ComboBox 内容的自动宽度

[英]Auto-width of ComboBox's content

Does anybody know a way to set the ComboBox 's content's width to autosize有人知道将ComboBox的内容宽度设置为自动调整大小的方法吗

I do not mean the ComboBox itself, just the opened content.我指的不是ComboBox本身,而是打开的内容。

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根据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() doesn't work for me, I suggest to use myCombo.GetItemText(obj). obj.ToString() 对我不起作用,我建议使用 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;
}

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 .此代码取自 codeproject: Adjust combo box drop down list width to最长字符串宽度 But I have modified it to work with comboboxes filled with any data (not only strings).但是我已经修改了它以使用填充了任何数据(不仅是字符串)的组合框。

Mostly the same code as in Javed Akram's second suggestion, but the width of the vertical scroll bar is added:与 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;
}

Use the code like this (on a form with a combobox with the name myComboBox):使用这样的代码(在带有名称为 myComboBox 的组合框的表单上):

myComboBox.Width = setWidth_comboBox(myComboBox);

Vote for algreat's answer below.投票支持下面的 algreat 答案。

I simply modified algreat's answer with code resize the entire control.我只是修改了 algreat 的答案,代码调整了整个控件的大小。

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;
}

Please see my solution below:请在下面查看我的解决方案:

   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;
        }

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);

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();
}

TComboBox.ItemWidth is the property you seek. TComboBox.ItemWidth 是您要寻找的属性。 It has the behavior you want without any coding.它具有您想要的行为,无需任何编码。 Just set it at design time or programmatically to something bigger than Width, and when the user pulls down the box they will get a wider list of choices.只需在设计时或以编程方式将其设置为大于 Width 的值,当用户拉下该框时,他们将获得更广泛的选择列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM