Auto-width of ComboBox's content

C#.NetWinformsCombobox

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

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

Solution 2 - C#

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

Solution 3 - C#

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

Solution 4 - C#

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

Solution 5 - C#

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

Solution 6 - C#

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

Solution 7 - C#

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

Solution 8 - C#

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

Solution 9 - C#

TComboBox.ItemWidth is the property you seek. 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionunicornView Question on Stackoverflow
Solution 1 - C#Javed AkramView Answer on Stackoverflow
Solution 2 - C#user2361362View Answer on Stackoverflow
Solution 3 - C#algreatView Answer on Stackoverflow
Solution 4 - C#matsolofView Answer on Stackoverflow
Solution 5 - C#Gary KindelView Answer on Stackoverflow
Solution 6 - C#user1779049View Answer on Stackoverflow
Solution 7 - C#Ismail SaifoView Answer on Stackoverflow
Solution 8 - C#Aaron SchooleyView Answer on Stackoverflow
Solution 9 - C#phrView Answer on Stackoverflow