Автоматическая ширина содержимого ComboBox - PullRequest
39 голосов
/ 30 января 2011

Кто-нибудь знает способ установить ширину содержимого ComboBox для автоматического изменения размера

Я не имею в виду сам ComboBox, только открытый контент.

Ответы [ 7 ]

64 голосов
/ 30 января 2011

Вы не можете использовать его напрямую.

Выполните трюк

Сначала выполните итерацию по всем элементам вашего списка, проверьте ширину каждого элемента, назначив текст метке.Затем проверяйте ширину каждый раз, если ширина текущего элемента становится больше, чем предыдущие элементы, а затем изменяйте максимальную ширину.

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 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;
}
14 голосов
/ 08 августа 2012

Вот очень элегантное решение. Просто подпишите ваш комбинированный список на этот обработчик событий:

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

Этот код был взят из кода проекта: Установите ширину выпадающего списка в поле со списком для наибольшей ширины строки . Но я изменил его для работы со списками, заполненными любыми данными (не только строками).

11 голосов
/ 08 мая 2013

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;
}
1 голос
/ 10 марта 2013

В основном тот же код, что и во втором предложении Джаведа Акрама, но добавлена ​​ширина вертикальной полосы прокрутки:

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);
0 голосов
/ 25 июня 2017

Старый, но классический, надеюсь, что работать достаточно быстро

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();
}
0 голосов
/ 19 июня 2016

Проголосуйте за ответ algreat ниже.

Я просто изменил ответ algreat с кодом изменения размера всего элемента управления.

Я бы просто добавил его в качестве комментария, но не смог бы добавить отформатированный код в комментарий.

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;
}
0 голосов
/ 30 апреля 2015

Это старый вопрос, но я просто наткнулся на него и объединил пару ответов для своего решения.Мне понравилась простота принятого ответа, но я хотел что-то, что будет работать с любым типом объекта в поле со списком.Я также хотел использовать метод через метод расширения.

    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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...