On a control I am using multiple attribute properties:
[Browsable(false)] [Bindable(false)] [EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Obsolete("", true)] public new Boolean AllowDrop;
I am using those properties on a lot of the other control properties as well.
I am wondering if there is a way to reduce the amount of code to write each time.
It would be nice if I could combine multiple attributes like this:
[Hidden(true)] public new Boolean AllowDrop;
Where the Hidden
Property would include all the attributes above. So there is only 1 single line of code.
Maybe there is also a way to combine the attributes in a macro or something?
I am aware that there are other ways of hiding properties but I chose the way of using attributes.
Thanks
What is Aggregation? → In simpler terms it refers to combining two or more attributes (or objects) into single attribute (or object).
To combine attributes, you must specify the source attribute class and the target attribute class: The source attribute class (Paste Values of Attribute) is the attribute class whose instances you want to convert. You can specify that this attribute class is deleted after the attribute classes are combined.
a) Merge them individually For this, select “Select individual items” and then enter the attributes you want to merge. After that, select the attribute into which you want to merge all the attributes in the “With this item” field.
Advertisements. An attribute is a declarative tag that is used to convey information to runtime about the behaviors of various elements like classes, methods, structures, enumerators, assemblies etc. in your program. You can add declarative information to a program by using an attribute.
It depends to the framework which is using the attribute.
Combining attributes can be meaningful in order to the context which uses and interprets attributes. For example for those contexts which use .Net Type Description mechanisms you can customize the type description which .Net returns to consumers.
It's possible to provide custom metadata for types using the standard .Net mechanism for that purpose, registering a custom type descriptor for your object.
The idea will work this way, you create a custom type descriptor for your type. In the custom type descriptor, you return custom property descriptors for the properties of your type and in the property descriptor, you return a custom set of attributes for the property.
The approach requires more code, but it's really interesting and shares some good idea about how to provide custom metadata for your types:
IMetedataAttribute Interface
The usage is providing an standard way to create MetaDataAttributes. Each attribute which implements this interface will be used as metadata and instead of the attribute, those one which it returns in Process
method will be used:
public interface IMetadatAttribute { Attribute[] Process(); }
Sample MetadataAttribute
It's a sample metadata attribute which returns some attribute instead when processing the attribute:
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; } }
Property Descriptor
This class will be used by the custom type descriptor to provide a custom list of attributes for the property:
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; } // } }
Type Descriptor
This is the type descriptor which provides a custom description for your type. In this example it uses custom property descriptors to provide custom attributes set for the properties of your class:
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); } }
Typedescriptor Provider
This class will be used in the attribute above your type to introduce the custom type descriptor which we created as the metadata engine for the type:
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); } }
Sample Class
Here is my sample class which its Name
property is decorated using MySampleMetadataAttribute
and the class itself is registered to use our custom type descriptor provider:
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))] public class MySampleClass { public int Id { get; set; } [MySampleMetadataAttribue] [DisplayName("My Name")] public string Name { get; set; } }
To see the result it's enough to create an instance of the class and see the result in PropertyGrid
:
var o = new MySampleClass(); this.propertyGrid1.SelectedObject = o;
Some notes on answer
PropertyGrid
control which works with type description.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With