Have you ever created a UserControl and needed to get rid of all those properties that don't seem to be applicable on ASP.NET  4.5.2 Hosting UK? And what concerning the events? looking and predominate the properties with the BrowsableAttribute set to false is awkward, particularly since a number of these properties area unit virtual, whereas others are not (need to be declared as 'new'). this method removes the unwanted properties and events by merely adding their names to an inventory.

I am presently writing an impact that performs image transitions, and am designing a separate article for that. when overloading variety of properties from the base class, and adding the [Browsable(false)] attribute to them, I started thinking there should be the way to try and do this the base the code itself. I used this method to get rid of unwanted properties and events from that control, and that i felt that the technique used merited its own article.

The VS designer and editor uses the TypeDescriptor of your object to get an inventory of its members (methods, properties and events) that ar offered. By implementing the ICustomTypeDescriptor on your class, you get to settle on that of those are literally available to the host of the object. This makes it potential to filter any of the member you do not wish employed by the consumer of the control.

public partial class ucImageShow : UserControl , ICustomTypeDescriptor {
    ...    
}
}

Most of the implentation uses the static ways of the TypeDescriptor object to come all the data from the framework. For the required ways, we have a tendency to simply acquire that info, and separate out no matter we do not need. Below is my implementation for the image transitioning control.

public AttributeCollection GetAttributes() {
    return TypeDescriptor.GetAttributes(this, true);

}

public string GetClassName() {

    return TypeDescriptor.GetClassName(this, true);

}

public string GetComponentName() {

    return TypeDescriptor.GetComponentName(this, true);

}

public TypeConverter GetConverter() {

    return TypeDescriptor.GetConverter(this, true);

}

public EventDescriptor GetDefaultEvent() {

    return TypeDescriptor.GetDefaultEvent(this, true);

}

public PropertyDescriptor GetDefaultProperty() {

    return TypeDescriptor.GetDefaultProperty(this, true);

}

public object GetEditor(Type editorBaseType) {

    return TypeDescriptor.GetEditor(this, editorBaseType, true);

}

public EventDescriptorCollection GetEvents(Attribute[] attributes) {
    EventDescriptorCollection orig = TypeDescriptor.GetEvents(this, attributes, true);

    return FilterEvents(orig);

}

public EventDescriptorCollection GetEvents() {

    EventDescriptorCollection orig = TypeDescriptor.GetEvents(this, true);

    return FilterEvents(orig);

}

public PropertyDescriptorCollection GetProperties(Attribute[] attributes) {
    PropertyDescriptorCollection orig = TypeDescriptor.GetProperties(this, attributes, true);

    return FilterProperties(orig);

}

public PropertyDescriptorCollection GetProperties() {
    PropertyDescriptorCollection orig = TypeDescriptor.GetProperties(this, true);

    return FilterProperties(orig);

}

public object GetPropertyOwner(PropertyDescriptor pd) {

    return this;
}

Filtering the events and properties is solely a making a replacement collection, and adding all members of the present collection that don't meet the filter criteria. This new collection then replaces the first collection for the come back of the ICustomTypeDescriptor method.

private string[] _excludeBrowsableProperties = {
    "AutoScroll",

    "AutoScrollOffset",

   "AutoScrollMargin",

    "AutoScrollMinSize",

    "AutoSize",

    "AutoSizeMode",

    "AutoValidate",

    "CausesValidation",

    "ImeMode",

  "RightToLeft",

    "TabIndex",
   
"TabStop"

};

private string[] _excludeBrowsableEvents = {
    "AutoSizeChanged",
  
"AutoValidateChanged",
  
"BindingContextChanged",

   "CausesValidationChanged",

    "ChangeUICues",

    "ImeModeChanged",

    "RightToLeftChanged",

    "Scroll",

    "TabIndexChanged",

    "TabStopChanged",

    "Validated",

    "Validating"

};

private PropertyDescriptorCollection FilterProperties(PropertyDescriptorCollection originalCollection) {

    // Create an enumerator containing only the properties that are not in the provided list of property names

    // and fill an array with those selected properties

    IEnumerable<PropertyDescriptor> selectedProperties = originalCollection.OfType<PropertyDescriptor>().Where(p => !_excludeBrowsableProperties.Contains(p.Name));

    PropertyDescriptor[] descriptors = selectedProperties.ToArray();

    // Return a PropertyDescriptorCollection containing only the filtered descriptors

    PropertyDescriptorCollection newCollection = new PropertyDescriptorCollection(descriptors);

    return newCollection;

}

private EventDescriptorCollection FilterEvents(EventDescriptorCollection origEvents) {

    // Create an enumerator containing only the events that are not in the provided list of event names

    // and fill an array with those selected events

    IEnumerable<EventDescriptor> selectedEvents = origEvents.OfType<EventDescriptor>().Where(e => !_excludeBrowsableEvents.Contains(e.Name));

    EventDescriptor[] descriptors = selectedEvents.ToArray();

    // Return an EventDescriptorCollection containing only the filtered descriptors

    EventDescriptorCollection newCollection = new EventDescriptorCollection(descriptors);

    return newCollection;

}

As you can see on the example above, filters the properties and events supported their name. However, it might not take a lot of effort to filter them on the other criteria, for example the existance and/or worth of an attribute, or the property kind. This technique not solely removes access to the properties from the VS designer, however additionally from the editor and compiler. this implies that it'll not turn out any designer generated code for these properties.

The draw back of this is often that if the control is placed on a form, then a property is excluded that the designer has already generated code for, then the complete form can become invalid. to repair that, you would like to go into the form.designer.cs module and take away any references to the offending property. I discovered this the laborious method by excluding the TabIndex property.