有没有办法为 class 的特定 属性 隐藏一些枚举值?
Is there a way for hiding some enum values for specific property of class?
我有 enum 让我们举个例子:
public enum Color
{
red,
green,
blue
}
并且有两个类。其中有 属性 of 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 Forms Designer 中,我只想从 ClassB 的 Color 枚举中隐藏红旗。
我知道我可以创建一个单独的枚举。但为什么重复值?我只举了一个简单的例子。
Something I guess might help for superior who can help me at it.
Descriptor API. which I hate. ;(
可能是 TypeDescriptor.AddAttributes(object, new BrowsableAttribute(false));
这个answer在这种情况下不起作用。我不想将 Browsable
属性应用于枚举标志,因为它在 属性 网格中为所有 类 隐藏了该标志。我希望能够仅隐藏特定 类 的特定枚举值,而不是所有 类.
帮助您在 PropertyGrid
中显示枚举值的 class 是 EnumConverter
and the method which is responsible to list enum values in GetStandardValues
。
因此,作为一个选项,您可以创建自定义枚举转换器 class,方法是从 EnumConverter
派生,并将其 GetStandardValues
覆盖为 return 标准值,基于属性.
的特定属性
如何在TypeConverter
方法中获取属性的属性等上下文信息?
ITypeDescriptorContext
class 的一个实例被传递给 TypeConverter
方法的 context
参数。使用 class,您可以访问正在编辑的对象,并且正在编辑的 属性 的 属性 描述符具有一些有用的属性。在这里你可以依靠
上下文的 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; }
}
我有 enum 让我们举个例子:
public enum Color
{
red,
green,
blue
}
并且有两个类。其中有 属性 of 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 Forms Designer 中,我只想从 ClassB 的 Color 枚举中隐藏红旗。
我知道我可以创建一个单独的枚举。但为什么重复值?我只举了一个简单的例子。
Something I guess might help for superior who can help me at it.
Descriptor API. which I hate. ;(
可能是 TypeDescriptor.AddAttributes(object, new BrowsableAttribute(false));
这个answer在这种情况下不起作用。我不想将 Browsable
属性应用于枚举标志,因为它在 属性 网格中为所有 类 隐藏了该标志。我希望能够仅隐藏特定 类 的特定枚举值,而不是所有 类.
帮助您在 PropertyGrid
中显示枚举值的 class 是 EnumConverter
and the method which is responsible to list enum values in GetStandardValues
。
因此,作为一个选项,您可以创建自定义枚举转换器 class,方法是从 EnumConverter
派生,并将其 GetStandardValues
覆盖为 return 标准值,基于属性.
如何在TypeConverter
方法中获取属性的属性等上下文信息?
ITypeDescriptorContext
class 的一个实例被传递给 TypeConverter
方法的 context
参数。使用 class,您可以访问正在编辑的对象,并且正在编辑的 属性 的 属性 描述符具有一些有用的属性。在这里你可以依靠
上下文的 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; }
}