在ComboBox中显示带有空格的枚举

14

我有一个枚举,例如:

enum MyEnum
{
My_Value_1,
My_Value_2
}

使用“:

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));

现在我的问题是:如何将"_"替换为" ",使得项目中有空格而非下划线?并且数据绑定对象仍然能够正常工作。


请参考此答案,解决如何在C#枚举中重写ToString方法的问题。 - John Saunders
7个回答

15

如果您可以访问 .NET Framework 3.5,那么可以像这样做:

Enum.GetValues(typeof(MyEnum))
    .Cast<MyEnum>()
    .Select(e=> new
                {
                    Value = e,
                    Text = e.ToString().Replace("_", " ")
                });
这将为您返回一个匿名类型的IEnumerable,其中包含一个"Value"属性,该属性是枚举类型本身,并且一个"Text"属性,该属性将包含替换下划线为空格的枚举器的字符串表示形式。
"Value"属性的目的是让您可以准确地知道在组合框中选择了哪个枚举器,而无需获取下划线并解析字符串。

我已经尝试过了,但现在遇到问题:cboSurveyRemarksType.SelectedItem……我无法设置选定的项目……该怎么办? - jame
cboBLVisual.SelectedItem = Enum.Value;为什么不起作用? - jame
SelectedItem不起作用是因为它引用了我们使用查询创建的匿名类型(具有Value/Text属性的类型),您必须使用SelectedValue属性,cboBLVisual.SelectedValue = Enum.Value。 - Christian C. Salvadó
cboBLVisual.SelectedValue = Enum.Value 这行代码给我显示错误...错误信息如下:无法在没有设置 ValueMember 的 ListControl 中设置 SelectedValue。 - jame
1
你会如何使用这个呢?我猜你会将这个LINQ语句的结果设置为“DataSource”属性。然后,你会将“ValueMember”属性设置为“Text”吗?你怎么才能得到枚举值呢?我不确定你该如何将“SelectedItem”强制转换回从LINQ语句中得到的匿名类型。 - Jeff B

6
如果您能够修改定义枚举的代码,使得您可以在不修改实际枚举值的情况下添加属性,则可以使用此扩展方法。
/// <summary>
/// Retrieve the description of the enum, e.g.
/// [Description("Bright Pink")]
/// BrightPink = 2,
/// </summary>
/// <param name="value"></param>
/// <returns>The friendly description of the enum.</returns>
public static string GetDescription(this Enum value)
{
  Type type = value.GetType();

  MemberInfo[] memInfo = type.GetMember(value.ToString());

  if (memInfo != null && memInfo.Length > 0)
  {
    object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

    if (attrs != null && attrs.Length > 0)
    {
      return ((DescriptionAttribute)attrs[0]).Description;
    }
  }

  return value.ToString();
}

4

试一下这个...

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum))
                           .Cast<MyEnum>()
                           .Select(e => new { Value = e, Description = e.ToString().Replace("_"," ") })
                           .ToList();
comboBox1.DisplayMember = "Description";
comboBox1.ValueMember = "Value";

尽管如此,我更倾向于使用“描述”属性(正如Steve Crane的回答所述)


3

手动填充下拉框并在枚举中进行字符串替换。

以下是具体步骤:

comboBox1.Items.Clear();
MyEnum[] e = (MyEnum[])(Enum.GetValues(typeof(MyEnum)));
for (int i = 0; i < e.Length; i++)
{
    comboBox1.Items.Add(e[i].ToString().Replace("_", " "));
}

要设置组合框的已选项,请按以下步骤操作:

comboBox1.SelectedItem = MyEnum.My_Value_2.ToString().Replace("_", " ");

我的枚举有10个值,如何手动设置它们......你有没有任何动态设置的想法? - jame
循环遍历枚举中的所有值。请参见:https://dev59.com/V3NA5IYBdhLWcg3wa9Gp - Dan Walker
我已经编辑了我的回答,包括你需要做什么。 - Kelsey
我已经更新了我的答案,向您展示如何设置所选项目。 - Kelsey

1
如果您使用的是.NET 3.5,您可以添加这个扩展类:
public static class EnumExtensions {

    public static List<string> GetFriendlyNames(this Enum enm) {
        List<string> result = new List<string>();
        result.AddRange(Enum.GetNames(enm.GetType()).Select(s => s.ToFriendlyName()));
        return result;
    }

    public static string GetFriendlyName(this Enum enm) {
        return Enum.GetName(enm.GetType(), enm).ToFriendlyName();
    }

    private static string ToFriendlyName(this string orig) {
        return orig.Replace("_", " ");
    }
}

然后设置你的组合框,你只需要这样做:

MyEnum val = MyEnum.My_Value_1;
comboBox1.DataSource = val.GetFriendlyNames();
comboBox1.SelectedItem = val.GetFriendlyName();

这应该适用于任何枚举类型。您需要确保在包含EnumExtensions类的命名空间中使用using语句。


0

我认为将内部枚举名称映射到用户空间并不是一个很好的想法。如果您重构枚举值,会怎么样呢?因此,我建议您查看这篇文章(本地化.NET 枚举)。使用该文章中描述的技术,您不仅可以将“_”替换为空格,还可以为不同的语言制作不同的枚举表示(使用资源)。


动态地是什么意思?您只需将所有值绑定到组合框中。我提到的文章完全符合这一点。 - arbiter

0

我喜欢Kelsey的回答,尽管我会使用另一个变量而不是'e',比如'en',这样答案可以在事件处理程序中更轻松地使用;事件处理程序中的'e'往往是EventArgs参数。 至于LINQ和IEnumerable方法,对于非WPF ComboBox在.NET 3.5中似乎更复杂和难以适应。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接