web-dev-qa-db-ja.com

ComboBoxのコンテンツの自動幅

ComboBoxのコンテンツの幅を自動サイズに設定する方法を知っている人はいますか

ComboBoxそのものではなく、開かれたコンテンツだけを意味します。

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

[〜#〜] or [〜#〜]

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

Javed Akramの2番目の提案とほぼ同じコードですが、垂直スクロールバーの幅が追加されています。

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