Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 编辑PropertyGrid中枚举成员的显示名称_C#_.net - Fatal编程技术网

C# 编辑PropertyGrid中枚举成员的显示名称

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

我有一个属性网格,用户可以使用它为我的应用程序中使用的任何插件配置对象。我希望能够告诉编写插件的开发人员为其成员使用ComponentModel属性,如下所示:

[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
}