it-roy-ru.com

Автоматическая ширина содержимого ComboBox

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

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

37
unicorn

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

Сделай трюк

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

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;
}
60
Javed Akram

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

 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: Отрегулируйте ширину выпадающего списка поля со списком до самой длинной ширины строки . Но я изменил его для работы с полями со списком, заполненными любыми данными (не только строками).

14
algreat

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

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

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

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

    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);
0
Aaron Schooley

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

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
user1779049

Проголосуйте за ответ 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
Gary Kindel