Removing a control’s behavior

21 11 2006

In Programming .NET Components, Juval Löwy explains the reasoning behind and how to use the EventHandlerList class (It’s used internally in the Control & derived classes to store event subscriptions).

I found that this architecture easily supports the removal of all behavior*:

public static void ClearEventHandlerList (Component component) {
    if (component == null)
        throw new ArgumentNullException ("component");
    FieldInfo fieldInfo = (typeof (Component)).GetField ("events",
        BindingFlags.Instance |
        BindingFlags.NonPublic |
        BindingFlags.DeclaredOnly |
        BindingFlags.ExactBinding);
    EventHandlerList currentList =
        fieldInfo.GetValue (component) as EventHandlerList;
    if (currentList != null)
        currentList.Dispose ();
    fieldInfo.SetValue (component, null);
}

For example, a security component could easily remove a control’s behavior* when the user does not have permission. Keep in mind that this is not a substitute for declarative or imperative security checks - other methods can continued to refer to the control’s state or subscribe to its events in the future.

Other benefits include the ability for a security component to use a ToolTip to notify the user of access denied (ToolTips do not function on disabled controls).

button.Click += new System.EventHandler (this.button_Click);
// the button_Click method is called when the button is clicked
...
ClearEventHandlerList (button);
// button does not have a click event subscriber anymore
// (button_Click is no longer called when the button is clicked)

* behavior as defined by event subscriptions where the event accessor implementation uses the EventHandlerList class.