【问题标题】:Is there a way for hiding some enum values for specific property of class?有没有办法为类的特定属性隐藏一些枚举值?
【发布时间】:2019-11-25 01:10:37
【问题描述】:

我有 enum 比如说:

public enum Color
{
  red,
  green,
  blue
}

并且有两个班级。具有 enum 的属性。

public class ClassA
{
    public Color Color{get;set;}
}

public class ClassB
{
    [InvisibleFlag(Color.red)]  // I want something like that
    public Color Color{get;set;}
}

现在在 Windows 窗体设计器中,我只想从 ClassB 的 Color 枚举中隐藏红旗。

我知道我可以创建一个单独的枚举。但为什么重复值?我只举了一个简单的例子。

我想可能会对可以帮助我的上级有所帮助。

描述符 API。我讨厌。 ;(

也许像TypeDescriptor.AddAttributes(object, new BrowsableAttribute(false));

这个answer 在这种情况下不起作用。我不想将Browsable 属性应用于枚举标志,因为它在所有类的属性网格中隐藏了该标志。我希望能够仅隐藏特定类的特定枚举值,而不是所有类。

【问题讨论】:

  • 您可以使用 TypeConverter,其中,在 GetStandardValues() 方法覆盖中,您可以过滤 Enum 值以返回排除 InvisibleFlag 属性指定的值的新集合。您还必须覆盖 CanConvertFromConvertFrom,以将 Enum 的字符串表示形式转换为 Enum 值。您还需要使用两个构造函数创建InvisibleFlag 自定义属性:一个接受枚举类型,一个接受字符串。应使用[DefaultValue(...)] 属性,以避免默认分配给排除的枚举值。
  • @Ňɏssa:“这与 Windows 窗体设计器毫无关系”——不是吗?他们似乎在要求专门调整设计器中的行为。 IE。防止 red 值在设计器中显示时成为类的属性网格中的选项。

标签: c# .net winforms windows-forms-designer propertygrid


【解决方案1】:

帮助您在PropertyGrid 中显示枚举值的类是EnumConverter,以及负责在GetStandardValues 中列出枚举值的方法。

因此,作为一种选择,您可以通过从 EnumConverter 派生并覆盖其 GetStandardValues 来创建自定义枚举转换器类,以根据您对该属性拥有的特定属性返回标准值。

如何在TypeConverter方法中获取属性属性等上下文信息?

ITypeDescriptorContext 类的实例被传递给TypeConverter 方法的context 参数。使用该类,您可以访问正在编辑的对象,并且正在编辑的属性的属性描述符具有一些有用的属性。在这里,您可以依赖上下文的
PropertyDescriptor 属性并获取Attributes 并检查是否已为该属性设置了我们感兴趣的特定属性。

示例

[TypeConverter(typeof(ExcludeColorTypeConverter))]
public enum Color
{
    Red,
    Green,
    Blue,
    White,
    Black,
}
public class ExcludeColorAttribute : Attribute
{
    public Color[] Exclude { get; private set; }
    public ExcludeColorAttribute(params Color[] exclude)
    {
        Exclude = exclude;
    }
}
public class ExcludeColorTypeConverter : EnumConverter
{
    public ExcludeColorTypeConverter() : base(typeof(Color))
    {
    }
    public override StandardValuesCollection GetStandardValues(
        ITypeDescriptorContext context)
    {
        var original = base.GetStandardValues(context);
        var exclude = context.PropertyDescriptor.Attributes
            .OfType<ExcludeColorAttribute>().FirstOrDefault()?.Exclude
            ?? new Color[0];
        var excluded = new StandardValuesCollection(
            original.Cast<Color>().Except(exclude).ToList());
        Values = excluded;
        return excluded;
    }
}

作为使用示例:

public class ClassA
{
    public Color Color { get; set; }
}

public class ClassB
{
    [ExcludeColor(Color.White, Color.Black)]
    public Color Color { get; set; }
}

【讨论】:

  • Reza 我真的想说一个真正的男人就是真正的男人,你为我们做更难的事情对你来说很容易。谢谢你一个真正的男人。
  • Reza,抱歉,我省略了 Values = 排除,并且代码仍然有效?这个属性重要吗?
  • ColorClassA 的属性是一个没有ExcludeColor 的属性示例,它仍然有效。事实上,通过使用[TypeConverter(typeof(ExcludeColorTypeConverter))] 装饰枚举,我们告诉这个枚举类型的所有属性都应该使用这个类型转换器。然后在ExcludeColorTypeConverterGetStandardValues 方法中,我们检查属性是否有任何ExcludeColor 属性,然后我们从列表中排除这些值,否则我们显示原始列表值(所有枚举)。
猜你喜欢
  • 2014-09-11
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 2015-03-17
  • 2022-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多