C# 编辑PropertyGrid中枚举成员的显示名称
我有一个属性网格,用户可以使用它为我的应用程序中使用的任何插件配置对象。我希望能够告诉编写插件的开发人员为其成员使用ComponentModel属性,如下所示:C# 编辑PropertyGrid中枚举成员的显示名称,c#,.net,C#,.net,我有一个属性网格,用户可以使用它为我的应用程序中使用的任何插件配置对象。我希望能够告诉编写插件的开发人员为其成员使用ComponentModel属性,如下所示: [CategoryAttribute("On Screen Display Settings"), DescriptionAttribute("Whether or not to show the session timer."), DisplayName("Show Session Timer")] public bool Sh
[CategoryAttribute("On Screen Display Settings"),
DescriptionAttribute("Whether or not to show the session timer."),
DisplayName("Show Session Timer")]
public bool ShowTimer
{
get;
set;
}
这很有效。现在,我希望枚举的成员也能够被编辑。i、 e
public enum Resolution_ : byte
{
DCIF,
CIF,
QCIF,
[DisplayName("4CIF")]
CIF4,
[DisplayName("2CIF")]
CIF2
}
这样它们就会显示在PropertyGrid的列表中,如下所示:
DCIF
CIF
QCIF
CIF4
CIF2
以及他们可能随身携带的任何描述和显示名称
似乎我只能用属性、事件和方法来实现这一点。有人知道如何为枚举执行此操作吗?您必须创建一个
EnumConverter
类,并使用TypeConverter
属性装饰您的属性才能执行此操作
看这个,这是一个有趣的例子:
假设您希望列表中有两个以上的项。布尔类型不够;您需要为枚举中的每个元素设置具有名称的描述属性
在另一个类中,您需要使用类型EnumConverter
第三,需要设置属性TypeConverter以显示属性
可以将自定义实现附加到类型为枚举的属性,并重写和,以返回要显示在PropertyGrid下拉列表中的自定义项列表。然后,可以重写ConvertFrom/ConvertTo方法来处理值与枚举类型之间的转换
您可能还希望重写并使其返回“true”,以便用户无法在属性值中键入任何内容
比如说:
public class MyTypeConverter : TypeConverter
{
//Override GetStandardValuesExclusive,
//GetStandardValues and GetStandardValuesSupported
}
public class SomeClass
{
[TypeConverter(typeof(MyTypeConverter))]
public Resolution SomePropertry
{
...
}
}
在GetStandardValues/ConvertFrom/ConvertTo的实现中,您可以使用反射来提取DisplayNameAttribute(或DescriptionAttribute,可能更适合此任务)各种枚举成员的属性,以显示该文本,而不是硬编码要显示的项列表。我给出的答案有一个工作示例。下面是该示例中您需要的特定代码:
/// <summary>
/// This attribute is used to represent a string value
/// for a value in an enum.
/// </summary>
public class StringValueAttribute : Attribute {
#region Properties
/// <summary>
/// Holds the stringvalue for a value in an enum.
/// </summary>
public string StringValue { get; protected set; }
#endregion
#region Constructor
/// <summary>
/// Constructor used to init a StringValue Attribute
/// </summary>
/// <param name="value"></param>
public StringValueAttribute(string value) {
this.StringValue = value;
}
#endregion
}
public static class MyExtension
{
public static string GetStringValue(this Enum value)
{
// Get the type
Type type = value.GetType();
// Get fieldinfo for this type
FieldInfo fieldInfo = type.GetField(value.ToString());
// Get the stringvalue attributes
StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
typeof(StringValueAttribute), false) as StringValueAttribute[];
// Return the first if there was a match.
return attribs.Length > 0 ? attribs[0].StringValue : null;
}
public static String[] GetEnumNames(Type t)
{
Array enumValueArray= Enum.GetValues(t);
string[] enumStrings = new String[enumValueArray.Length];
for(int i = 0; i< enumValueArray.Length; ++i)
{
enumStrings[i] = GetStringValue((test)enumValueArray.GetValue(i));
}
return enumStrings;
}
}
enum test
{
[StringValue("test ONE")]
test1,
[StringValue("test TWO")]
test2
}
//
///此属性用于表示字符串值
///用于枚举中的值。
///
公共类StringValueAttribute:属性{
#区域属性
///
///保存枚举中某个值的stringvalue。
///
公共字符串StringValue{get;protected set;}
#端区
#区域构造函数
///
///用于初始化StringValue属性的构造函数
///
///
public StringValueAttribute(字符串值){
this.StringValue=value;
}
#端区
}
公共静态类MyExtension
{
公共静态字符串GetStringValue(此枚举值)
{
//获取类型
Type Type=value.GetType();
//获取此类型的fieldinfo
FieldInfo FieldInfo=type.GetField(value.ToString());
//获取stringvalue属性
StringValueAttribute[]attribs=fieldInfo.GetCustomAttributes(
typeof(StringValueAttribute),false)作为StringValueAttribute[];
//如果有匹配项,请返回第一个。
返回attribs.Length>0?attribs[0]。StringValue:null;
}
公共静态字符串[]GetEnumNames(类型t)
{
数组enumValueArray=Enum.GetValues(t);
string[]enumStrings=新字符串[enumValueArray.Length];
对于(int i=0;i
这似乎也能奏效:
[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayNameAttribute : System.ComponentModel.DisplayNameAttribute
{
public EnumDisplayNameAttribute(string data) : base(data) { }
}
public enum Resolution_ : byte
{
DCIF,
CIF,
QCIF,
[EnumDisplayName("4CIF")]
CIF4,
[EnumDisplayName("2CIF")]
CIF2
}
通过反射查找DisplayName属性的组件将找到一个,据我所知,这是可行的。这可能是个坏主意,有什么原因吗?谢谢!就这样。我不知道为什么,但在谷歌上呆了一个小时,我仍然没有找到那篇文章。很好,我以前在与PropertyGrid的斗争中没有遇到EnumConverter。超链接“在.NET中使用PropertyGrid”现在不正确。@EugeneMaksimov谢谢。我更新了答案,并删除了用户发布的示例代码,以防链接再次失效。@FrancescoDS好吧,如果您正在寻求帮助,我需要更多的信息。我喜欢这个想法的简单性,但不幸的是,它对我不起作用(不过,我正在创建Visual Studio选项页面,而不是vanilla PropertyGrids).这对我不起作用。我使用的是Windows窗体属性网格,它仍然只显示普通的枚举名称。
public class MyTypeConverter : TypeConverter
{
//Override GetStandardValuesExclusive,
//GetStandardValues and GetStandardValuesSupported
}
public class SomeClass
{
[TypeConverter(typeof(MyTypeConverter))]
public Resolution SomePropertry
{
...
}
}
/// <summary>
/// This attribute is used to represent a string value
/// for a value in an enum.
/// </summary>
public class StringValueAttribute : Attribute {
#region Properties
/// <summary>
/// Holds the stringvalue for a value in an enum.
/// </summary>
public string StringValue { get; protected set; }
#endregion
#region Constructor
/// <summary>
/// Constructor used to init a StringValue Attribute
/// </summary>
/// <param name="value"></param>
public StringValueAttribute(string value) {
this.StringValue = value;
}
#endregion
}
public static class MyExtension
{
public static string GetStringValue(this Enum value)
{
// Get the type
Type type = value.GetType();
// Get fieldinfo for this type
FieldInfo fieldInfo = type.GetField(value.ToString());
// Get the stringvalue attributes
StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
typeof(StringValueAttribute), false) as StringValueAttribute[];
// Return the first if there was a match.
return attribs.Length > 0 ? attribs[0].StringValue : null;
}
public static String[] GetEnumNames(Type t)
{
Array enumValueArray= Enum.GetValues(t);
string[] enumStrings = new String[enumValueArray.Length];
for(int i = 0; i< enumValueArray.Length; ++i)
{
enumStrings[i] = GetStringValue((test)enumValueArray.GetValue(i));
}
return enumStrings;
}
}
enum test
{
[StringValue("test ONE")]
test1,
[StringValue("test TWO")]
test2
}
[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayNameAttribute : System.ComponentModel.DisplayNameAttribute
{
public EnumDisplayNameAttribute(string data) : base(data) { }
}
public enum Resolution_ : byte
{
DCIF,
CIF,
QCIF,
[EnumDisplayName("4CIF")]
CIF4,
[EnumDisplayName("2CIF")]
CIF2
}