【问题标题】:How to bind an enumeration to combobox如何将枚举绑定到组合框
【发布时间】:2011-08-04 01:31:07
【问题描述】:

我会将枚举值与组合框控件绑定。

我已经写了这段代码:

cboPriorLogicalOperator.DataSource = Enum.GetValues(typeof(MyEnum))
    .Cast<MyEnum>()
    .Select(p => new { Key = (int)p, Value = p.ToString() })
    .ToList();

myComboBox.DisplayMember = "Value";
myComboBox.ValueMember = "Key";

效果很好,但我想知道是否有更简单的方法。

【问题讨论】:

  • 如果您的解决方案有效,为什么还要寻找更简单的解决方案?
  • @Ramhound:我认为也许有一个 direct 方式。我确实理解我的代码,但不是每个人都能简单地做到这一点。所以我找了一个更简单的。
  • @Homam 我不知道您是否打算那样做,但是当我为自己的解决方案仿照您的代码时,我必须反转我的选择语句中的键和值类型才能显示组合框中的值正确。您的方法最终在组合框中显示了键。
  • +1 为实际提供答案的问题!
  • @gonzobrains 已修复。

标签: c# winforms


【解决方案1】:

我觉得你的代码很漂亮!

唯一的改进是将代码放在扩展方法中。

编辑:

当我想到它时,您想要做的是使用定义中的Enum,而不是枚举的实例,这是扩展方法所必需的。

我找到了这个question,它很好地解决了这个问题:

public class SelectList
{
    // Normal SelectList properties/methods go here

    public static SelectList Of<T>()
    {
       Type t = typeof(T);
       if (t.IsEnum)
       {
           var values = from Enum e in Enum.GetValues(t)
                        select new { ID = e, Name = e.ToString() };
           return new SelectList(values, "Id", "Name");
       }
       return null;
    }
}

// called with 
var list = SelectList.Of<Things>();

只有您可能想要返回 Dictionary&lt;int, string&gt; 而不是 SelectList,但您明白了。

EDIT2:

这里我们提供一个涵盖您正在查看的案例的代码示例。

public class EnumList
{
    public static IEnumerable<KeyValuePair<T, string>> Of<T>()
    {
        return Enum.GetValues(typeof (T))
            .Cast<T>()
            .Select(p => new KeyValuePair<T, string>(p, p.ToString()))
            .ToList();
    }
}

或者这个版本,密钥是int

public class EnumList
{
    public static IEnumerable<KeyValuePair<int, string>> Of<T>()
    {
        return Enum.GetValues(typeof (T))
            .Cast<T>()
            .Select(p => new KeyValuePair<int, string>(Convert.ToInt32(p), p.ToString()))
            .ToList();
    }
}

【讨论】:

  • 我同意。我们已将 winforms 组合框扩展为我们自己的版本,并在其上添加了一个运行良好的 BindToEnum 方法。它看起来也很像这段代码。
  • 啊,他们在原始示例中错过了这一点。我想,在你的情况下,它会返回 Dictionary&lt;int, string&gt;
  • 我添加了一些您应该能够使用的真实代码。我使用了IEnumerable&lt;KeyValuePair&lt;int, string&gt;&gt;,因为当我使用枚举HttpStatusCode 进行测试时,我遇到了关键重复问题,这让我选择了这个而不是Dictionary&lt;int, string)。但是,当使用int 作为键时,不会发生重复错误。
【解决方案2】:
private void Form1_Load(object sender, EventArgs e)
{
    comboBox1.DataSource = Enum.GetValues( typeof(Gender));
    Array gen = Enum.GetValues(typeof(Gender));
    List<KeyValuePair<string, char>> lstgender = new List<KeyValuePair<string,char>>();
    foreach(Gender g in gen)
        lstgender.Add(new KeyValuePair<string,char>(g.ToString(),((char)g)));
    comboBox1.DataSource = lstgender;
    comboBox1.DisplayMember = "key";
    comboBox1.ValueMember = "value"
}

private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show(comboBox1.SelectedValue.ToString());
}

public class Student
{
    public string stud_name { get; set; }
    public Gender stud_gen { get; set; }
}

public enum Gender
{
    Male='M',
    Female='F'
}

【讨论】:

    【解决方案3】:

    我最近遇到了一个问题,我有一个可以为空的枚举属性,需要将它绑定到 ComboBox。这是我想出的解决方案:

    using System;
    using System.Collections.Generic;
    
    namespace ActivitySchedule.Model
    {
        public class NullableEnum<T> where T : struct, IComparable
        {
            public string Display { get; private set; }
    
            public T? Value { get; private set; }
    
            public static implicit operator T?(NullableEnum<T> o)
            {
                return o.Value;
            }
    
            public static implicit operator NullableEnum<T>(T? o)
            {
                return new NullableEnum<T>
                {
                    Display = o?.ToString() ?? "NA",
                    Value = o
                };
            }
    
            private NullableEnum() { }
    
            public static IEnumerable<NullableEnum<T>> GetList()
            {
                var items = new List<NullableEnum<T>>
                {
                    new NullableEnum<T>
                    {
                        Display = "NA",
                        Value = null
                    }
                };
    
                var values = Enum.GetValues(typeof(T));
    
                foreach (T v in values)
                {
                    items.Add(v);
                }
    
                return items;
            }
        }
    }
    

    我将对象包装在 Controller 类中,并像这样更改属性的类型:

    private MyClass myClass;
    
    public NullableEnum<MyEnum> MyEnum
    {
        get { return this.myClass.MyEnum; }
        set { this.myClass.MyEnum = value.Value; }
    }
    

    (也可以是派生类并覆盖属性)

    我是这样使用的:

    var types = NullableEnum<MyEnum>.GetList();
    this.comboBox1.DataSource = types;
    this.comboBox1.DisplayMember = "Display";
    this.comboBox1.ValueMember = "Value";
    this.comboBox1.Bindings.Add("SelectedValue", myClassController, "MyEnum");
    

    【讨论】:

      【解决方案4】:
      foreach (int r in Enum.GetValues(typeof(MyEnum))) 
      {
           var item = new ListItem(Enum.GetName(typeof(MyEnum), r), r.ToString());
           ddl.Items.Add(item);
      }
      

      【讨论】:

        【解决方案5】:

        为什么不使用:

        myComboBox.DataSource  = Enum.GetValues(typeof(MyEnum))
        

        ?

        【讨论】:

        • 因为这不会绑定键/值对。要从组合框中获取值,您必须将 SelectedItem 强制转换为枚举。请参阅备注部分中的msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx
        • 我认为如果我们想在检索到的数据中设置条件,有问题的代码是相当不错的......否则你的代码会更好......
        猜你喜欢
        • 2018-11-12
        • 2020-02-07
        • 1970-01-01
        • 1970-01-01
        • 2016-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-20
        相关资源
        最近更新 更多