【问题标题】:ComboBox auto DropDownWidth regardless of DataSource typeComboBox 自动 DropDownWidth 与 DataSource 类型无关
【发布时间】:2021-11-19 18:54:47
【问题描述】:

我想根据下拉项目中最长的字符串调整任何ComboBox 下拉菜单的宽度。我希望这适用于任何带有项目的ComboBox,这意味着项目是字符串的对象、带有DisplayMember 集合的对象或DataTable。我 found some code 适用于字符串,但不适用于设置 DisplayMember

static void resizeCombo(ComboBox cb)
{
    cb.DropDownWidth = cb.Items.Cast<string>().Max(x => TextRenderer.MeasureText(x, cb.Font).Width);
}

在以下三个示例中,第一个只是字符串的示例将起作用,但以下两个不起作用(cb.Items.Cast&lt;string&gt;() 转换为字符串失败),并证明 DisplayMember 在绑定到不同类的源时会有所不同,所以我不能只使用“名称”,例如

var c = new string[] { "Name1", "Name2" };
comboBox.DataSource = c.ToList();
resizeCombo(comboBox);

var c1 = new Class1[] { new Class1() { ID = 1, Name1 = "Name1" }, new Class1() { ID = 2, Name1 = "Name2" } };
comboBox1.DisplayMember = "Name1";
comboBox1.ValueMember = "ID";
comboBox1.DataSource = c1.ToList();
resizeCombo(comboBox1);

var c2 = new Class2[] { new Class2() { ID = 2, Name2 = "Name1" }, new Class2() { ID = 2, Name2 = "Name2" } };
comboBox2.DisplayMember = "Name2";
comboBox2.ValueMember = "ID";
comboBox2.DataSource = c2.ToList();
resizeCombo(comboBox2);

我可以反映DisplayMember,并按名称查找字符串,它可以解决List&lt;class&gt; 的情况,但不能解决DataTable

我正在寻找一种方法来获取ComboBox 中的所有字符串,无论它们是如何添加的。有吗?

【问题讨论】:

    标签: c# winforms user-interface


    【解决方案1】:

    Combobox 有GetItemText 方法,该方法返回项目的字符串表示形式。

    这应该可行:

        static void resizeCombo(ComboBox cb)
        {
            if (cb.Items.Count == 0) cb.DropDownWidth = cb.Width;
            else
            {
                int maxWidth = int.MinValue;
                for (int i = 0; i < cb.Items.Count; i++)
                {
                    maxWidth = Math.Max(maxWidth, TextRenderer.MeasureText(cb.GetItemText(cb.Items[i]), cb.Font).Width);
                }
                if (cb.Items.Count > cb.MaxDropDownItems) maxWidth += SystemInformation.VerticalScrollBarWidth                    
                cb.DropDownWidth = maxWidth;
            }
        }
    

    使用 DataTable 进行测试:

            DataTable t = new DataTable();
            t.Columns.Add(new DataColumn("ID", typeof(int)));
            t.Columns.Add(new DataColumn("Name2", typeof(string)));
    
            t.Rows.Add(new object[] { 1, "Somename" });
            t.Rows.Add(new object[] { 2, "Some other name" });
    
            comboBox2.DisplayMember = "Name2";
            comboBox2.ValueMember = "ID";
            comboBox2.DataSource = t;
            resizeCombo(comboBox2);
    

    注意!要使其工作,请不要在表单的构造函数中使用 resize 函数。一旦表单已经启动并运行,就可以从 Load 事件或类似事件中使用它。

    【讨论】:

    • 效果很好,谢谢
    • 这如何与绑定到数据源的数据表一起工作?在这种情况下,项目是空的。
    • 不,这也适用于 DataTable 作为源。试试看。
    • 抱歉,我无法使用绑定到 DataTable 的 Winforms 组合框来完成这项工作。只是开始 if 结果为零。然后将 DropDownWidth 设置为零会引发异常,如此处所述docs.microsoft.com/en-us/dotnet/api/… 所以我真的很想知道你是如何让它工作的
    • 添加了我用来回答的 DataTable 测试代码。但是,是的,将宽度设置为 0 是一个愚蠢的想法。应该将其重置为组合框的宽度。
    猜你喜欢
    • 2011-02-23
    • 2010-10-27
    • 2011-11-14
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多