友好格式的枚举在组合框,CheckedListBoxes等使用 [英] Friendly-Format Enum for use in ComboBoxes, CheckedListBoxes, etc
问题描述
我想从枚举
在C#中使用选择值的组合框
或选择位掩码(用于枚举
s的在标记
属性)以的CheckedListBox
。我想办法的值添加到控制作为选择项目,并干净地告诉该用户已经选择。
I want to select values from an enum
in C# using a ComboBox
or select bitmasks (for enum
s with the Flags
attribute) with a CheckedListBox
. I want a way to add the values to the controls as selectable items, and cleanly tell which the user has selected.
我也想选择是明确的和pretty给用户。目前,我已经可以添加枚举
值到组合框
或的CheckedListBox
,但 Enum.ToString()
将返回标识符名称。帕斯卡尔Case是我不够好,但不适合我的用户。
I also want the selection to be clear and pretty to the user. Currently I can already add Enum
values to a ComboBox
or a CheckedListBox
, but Enum.ToString()
will return the identifier name. Pascal Case is good enough for me, but not for my users.
我想这是很容易code。我的意思是轻松。我想这仅仅是一个事后的界定和/或使用的任何 枚举
值。
I want this to be easy to code. I mean easy. I want this to be a mere afterthought to defining and/or using any enum
value.
现在我环顾四周,看到几个不错的解决方案。其中有些是在他们自己的方式更好,如如果你真的需要把自己的自定义说明一>,或把它一步,<一个href=\"http://stackoverflow.com/questions/796607/how-do-i-have-an-enum-bound-combobox-with-custom-string-formatting-for-enum-valu\">support多国语言的。你可以做假枚举了。但是,我一直在寻找,而他们都没有优雅和简洁的相当的组合 - 我的目的 - 为我写的。见下文。
Now I looked around and saw several nice solutions. Some of them are better in their own ways, like if you really need to put in your own custom descriptions, or to take it one step further, support multiple languages. You can do fake enums too. But I kept looking, and none of them had quite the combination of elegance and simplicity--for my purposes--as what I wrote. See below.
推荐答案
我的解决方案的基础是一个结构
,它可以包含枚举
的价值观和覆盖的ToString()
。
The basis of my solution is a struct
that can wrap Enum
values and override ToString()
.
输入了 EnumWrapper
:
public struct EnumWrapper
{
private readonly Enum e;
public EnumWrapper(Enum e) {
this.e = e;
}
public static implicit operator Enum(EnumWrapper wrapper) {
return wrapper.e;
}
public static explicit operator EnumWrapper(Enum e) {
return new EnumWrapper(e);
}
public override string ToString() {
return e.ToStringFriendly();
}
}
该方法 ToStringFriendly()
被定义为一个扩展方法上的枚举
:
The method ToStringFriendly()
is defined as an extension method on Enum
:
using System.Text.RegularExpressions;
public static class _Extensions
{
public static string ToStringFriendly(this Enum e)
{
string s = e.ToString();
// enforce a charset: letters, numbers, and underscores
s = Regex.Replace(s, "[^A-Za-z0-9_]", "");
// separate numbers from letters
s = Regex.Replace(s, "([a-zA-Z])([0-9])", "$1 $2");
// separate letters from numbers
s = Regex.Replace(s, "([0-9])([a-zA-Z])", "$1 $2");
// space lowercases before uppercase (word boundary)
s = Regex.Replace(s, "([a-z])([A-Z])", "$1 $2");
// see that the nice pretty capitalized words are spaced left
s = Regex.Replace(s, "(?!^)([^ _])([A-Z][a-z]+)", "$1 $2");
// replace double underscores with colon-space delimiter
s = Regex.Replace(s, "__", ": ");
// finally replace single underscores with hyphens
s = Regex.Replace(s, "_", "-");
return s;
}
}
现在,任何枚举
值添加到组合框,例如,
Now, to add any Enum
value to a ComboBox, for example,
comboBox.Items.Add((EnumWrapper)MyEnum.SomeValue);
和把它找回来了(空试验后,当然):
And to get it back out (after null-testing, of course):
MyEnum myValue = (MyEnum)(Enum)(EnumWrapper)comboBox.SelectedItem;
就是这样。现在什么是这种方法的优点和缺点是什么?
And that's it. Now what are the pros and cons of this approach?
- 您可以通过直接在枚举值(几乎)和你的控制。只投来回/从
EnumWrapper
。 - 这工作得很好与一些特殊情况下,所有的Pascal-套管
枚举
值。一个例子可能是一个叫值MyValue__DescriptionOf123_ENUMValue
这会来出ToStringFriendly()
为我的价值: 123-枚举值的 说明 - 力学(一
结构
和扩展方法),可一次书面和卷起的出路。有一个在每个枚举
没有额外的编码。这意味着它工作得很好如上作为枚举你没有写,假设帕斯卡尔情况下,它在.NET是一个很好的设想。的注:这就是为什么我会说<一href=\"http://stackoverflow.com/questions/796607/how-do-i-have-an-enum-bound-combobox-with-custom-string-formatting-for-enum-valu\">this回答,但是优雅,是不是比我更好的解决方案,因为它需要,你可以在的TypeConverter
属性添加到每个枚举
。的
- You can pass the enum values (almost) directly in and out of your controls. Just cast back and forth to/from
EnumWrapper
. - This works nicely for all Pascal-cased
Enum
values with a few special cases. One example might be a value calledMyValue__DescriptionOf123_ENUMValue
which would come out ofToStringFriendly()
as "My Value: Description of 123-ENUM Value". - The mechanics (a
struct
and an extension method) can be written once and tucked out of the way. There is no additional coding in eachEnum
. This means it works nicely as above for enums you didn't write, assuming Pascal case, which in .NET is a good assumption. Note: This is why I'd say this answer, however elegant, is not a better solution than mine, as it requires that you can add aTypeConverter
attribute to eachEnum
.
- 这不支持的自定义说明或多种语言。例如像值
Encoding.EBCDIC
的总是会来,通过为EBCDIC,不允许您手动输入扩展二元codeD十进制交换code ,更不用说其他语言。
- This doesn't support custom descriptions or multiple languages. For example a value like
Encoding.EBCDIC
will always come through as "EBCDIC" and does not allow you to manually type "Extended Binary Coded Decimal Interchange Code", much less other languages.
人们可以通过改变添加自定义的描述和多语言支持<$ C $ C> ToStringFriendly()做一个语言的查询进行去帕斯卡尔套管之前的价值。
One could add custom descriptions and multi-language support by changing ToStringFriendly()
to do a language-lookup for that value before de-Pascal-casing.
有关更多的正则表达式的乐趣,看到<一个href=\"http://stackoverflow.com/questions/3621464/camelcase-conversion-to-friendly-name-i-e-enum-constants-problems\">this螺纹。
For more Regex fun, see this thread.
这篇关于友好格式的枚举在组合框,CheckedListBoxes等使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!