在控件上,我正在使用多个属性属性:
[Browsable(false)] [Bindable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Obsolete("", true)] public new Boolean AllowDrop;
我也在许多其他控件属性上使用这些属性。
我想知道是否有一种方法可以减少每次编写的代码量。
如果可以像这样组合多个属性,那就太好了:
[Hidden(true)] public new Boolean AllowDrop;
该Hidden属性将包括以上所有属性。因此,只有1行代码。
Hidden
也许还有一种方法可以将属性组合到宏之类的东西中?
我知道还有其他隐藏属性的方法,但是我选择了使用属性的方法。
谢谢
这取决于使用该属性的框架。
组合属性对于使用和解释属性的上下文可能是有意义的。例如,对于那些使用.Net类型描述机制的上下文,您可以自定义.Net返回给使用者的类型描述。
为此,可以使用标准.Net机制为类型提供自定义元数据,并为对象注册自定义类型描述符。
通过为您的类型创建自定义类型描述符,该想法将以这种方式起作用。在自定义类型描述符中,您将为类型的属性返回自定义属性描述符,在属性描述符中,将为属性返回一组自定义属性。
该方法需要更多代码,但它确实很有趣,并且共享了一些有关如何为您的类型提供自定义元数据的好主意:
IMetedataAttribute接口
该用法提供了创建MetaDataAttributes的标准方法。实现此接口的每个属性都将用作元数据,并且将使用它在Process方法中返回的那些属性代替该属性:
Process
public interface IMetadatAttribute { Attribute[] Process(); }
样本MetadataAttribute
这是一个示例元数据属性,在处理属性时会返回一些属性:
public class MySampleMetadataAttribute : Attribute, IMetadatAttribute { public Attribute[] Process() { var attributes = new Attribute[]{ new BrowsableAttribute(false), new EditorBrowsableAttribute(EditorBrowsableState.Never), new BindableAttribute(false), new DesignerSerializationVisibilityAttribute( DesignerSerializationVisibility.Hidden), new ObsoleteAttribute("", true) }; return attributes; } }
属性描述符
此类将由自定义类型描述符使用,以提供该属性的自定义属性列表:
public class MyPropertyDescriptor : PropertyDescriptor { PropertyDescriptor original; public MyPropertyDescriptor(PropertyDescriptor originalProperty) : base(originalProperty) { original = originalProperty;} public override AttributeCollection Attributes { get { var attributes = base.Attributes.Cast<Attribute>(); var result = new List<Attribute>(); foreach (var item in attributes) { if(item is IMetadatAttribute) { var attrs = ((IMetadatAttribute)item).Process(); if(attrs !=null ) { foreach (var a in attrs) result.Add(a); } } else result.Add(item); } return new AttributeCollection(result.ToArray()); } } // Implement other properties and methods simply using return original // The implementation is trivial like this one: // public override Type ComponentType // { // get { return original.ComponentType; } // } }
类型描述符
这是类型描述符,为您的类型提供自定义描述。在此示例中,它使用自定义属性描述符为类的属性提供自定义属性集:
public class MyTypeDescriptor : CustomTypeDescriptor { ICustomTypeDescriptor original; public MyTypeDescriptor(ICustomTypeDescriptor originalDescriptor) : base(originalDescriptor) { original = originalDescriptor; } public override PropertyDescriptorCollection GetProperties() { return this.GetProperties(new Attribute[] { }); } public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>() .Select(p => new MyPropertyDescriptor(p)) .ToArray(); return new PropertyDescriptorCollection(properties); } }
类型描述符提供者
此类将在您的类型上方的属性中使用,以介绍我们创建的自定义类型描述符,作为该类型的元数据引擎:
public class MyTypeDescriptionProvider : TypeDescriptionProvider { public MyTypeDescriptionProvider() : base(TypeDescriptor.GetProvider(typeof(object))) { } public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) { ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(objectType, instance); return new MyTypeDescriptor(baseDescriptor); } }
样品课
这是我的示例类,其Name属性使用其修饰,MySampleMetadataAttribute并且该类本身已注册为使用我们的自定义类型描述符提供程序:
Name
MySampleMetadataAttribute
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))] public class MySampleClass { public int Id { get; set; } [MySampleMetadataAttribue] [DisplayName("My Name")] public string Name { get; set; } }
要查看结果,足以创建该类的实例并在中查看结果PropertyGrid:
PropertyGrid
var o = new MySampleClass(); this.propertyGrid1.SelectedObject = o;
关于答案的一些注意事项