Отображать перечисление в ComboBox с пробелами
У меня есть перечисление, например:
enum MyEnum
{
My_Value_1,
My_Value_2
}
С помощью:
comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
Но теперь мой вопрос: как заменить "_" на "" так, чтобы он стал
элементы с пробелами вместо подчеркивания? И что объект привязки данных все еще
работы
Ответы
Ответ 1
Если у вас есть доступ к Framework 3.5, вы можете сделать что-то вроде этого:
Enum.GetValues(typeof(MyEnum))
.Cast<MyEnum>()
.Select(e=> new
{
Value = e,
Text = e.ToString().Replace("_", " ")
});
Это вернет вам IEnumerable анонимного типа, который содержит свойство Value, которое является самим типом перечисления, и свойство Text, которое будет содержать строковое представление перечислителя с символами подчеркивания, замененными пробелом.
Цель свойства Value состоит в том, что вы можете точно знать, какой перечислитель был выбран в комбо, без необходимости возвращать подчеркивания и анализировать строку.
Ответ 2
Если вы можете изменить код, определяющий перечисление, чтобы вы могли добавлять атрибуты к значениям без изменения фактических значений перечисления, тогда вы можете использовать этот метод расширения.
/// <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();
}
Ответ 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("_", " ");
Ответ 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";
... хотя, я был бы более склонен использовать атрибут "Описание" (согласно ответу Стива Крена).
Ответ 5
Если вы используете .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();
Это должно работать с любым Enum. Вы должны убедиться, что у вас есть оператор using для пространства имен, включающего класс EnumExtensions.
Ответ 6
Я думаю, что это не очень хорошая идея - сопоставить внутреннее имя enum в пространстве пользователя. Что делать, если вы реорганизуете свою сумму перечисления? Поэтому я предлагаю вам взглянуть на статью (Локализация .NET Enums). Используя технику, описанную в этой статье, вы можете не только заменить "_" на пробелы, но и сделать другое представление перечисления для разных языков (используя ресурсы).
Ответ 7
Мне нравится ответ Келси, хотя я бы использовал другую переменную, отличную от "e", такую как "en", поэтому ответ можно использовать в обработчиках событий с меньшими затратами; 'e' в обработчиках событий имеет тенденцию быть аргументом EventArgs
.
Что касается подхода LINQ и IEnumerable
, мне представляется сложнее и сложнее адаптироваться для не WPF ComboBox
es с .NET 3.5