C# · CodeProject · Dotnet

Refactoring Hooking and Unhooking events TIP

Dear Reader,

Today i was fixing a bug w.r.t event handling. So as part of this there were couple of forms (classes basically) which were trying to hook to an KeyDown events and unhooking upon disposed. Basically the requirement is, for every customized control in the forms/panel, this keydown event should be hooked. So no matter which ever control (child/parent) has the focus, keydown event has to get fired. So as part of this implementation, the code goes like this:

Hooking events:
public void HookingEvents()
{
    IEnumerable < Controls > allControls =
            CollectUIControlsHelper.Instance.CollectAllControls(this);

    foreach (Control ctrl in allControls)
    {
        ctrl.KeyDown += new KeyEventHandler(OnControlKeyDownHandler);
    }
}

UnHooking events (Part of Dispose call):
public void UnHookingEvents()
{
    IEnumerable < Controls > allControls =
           CollectUIControlsHelper.Instance.CollectAllControls(this);

    foreach (Control ctrl in allControls)
    {
        ctrl.KeyDown -= new KeyEventHandler(OnControlKeyDownHandler);
    }
}

As you can see from the above code, its pretty clear that the first method is just collecting all the controls from parent to child from the current form/panel/control via a method CollectAllControls(this). And does the opposite in UnhookingEvents. Do note that these methods are called in any fashion by the usage code. Hence every call has to fetch all the child controls.

Yes i do agree that this code is noting of great. But the annoying thing for me or primary concern for me was to see this code getting repetitive in many forms or classes across my application.

So i wanted to make this above code perhaps more common so that any form which wishes to hook for Keydown events can just reuse this code. As part of that effort, i came up with this simple solution as shown in the below code:

class KeyDownEventsHelper
{
    private static readonly KeyDownEventsHelper m_Instance =
             new KeyDownEventsHelper();

    public static KeyDownEventsHelper Instance
                   { get { return m_Instance; } }

    private KeyDownEventsHelper() { }
    static KeyDownEventsHelper() { }

    public void HookingEvents(Control control,
             Action<object,KeyEventArgs> eventHandler)
    {
        IEnumerable < Control > allControls =
          CollectUIControlsHelper.Instance.CollectAllControls(control);

        foreach (Control ctrl in allControls)
        {
            ctrl.KeyDown += new KeyEventHandler(eventHandler);
        }
    }

    public void UnHookingEvents(Control control,
            Action<object, KeyEventArgs> eventHandler)
    {
        IEnumerable < Control > allControls =
          CollectUIControlsHelper.Instance.CollectAllControls(control);

        foreach (Control ctrl in allControls)
        {
            ctrl.KeyDown -= new KeyEventHandler(eventHandler);
        }
    }
}

As you can see from the above code, it is a singleton class which publishes 2 methods for hooking and unhooking. So as part of the this methods, i have provided a delegate for the event handler to invoke upon any events generated. So each class can provide its own even handlers for hooking.

Now i am feeling a bit relaxed as i could reduce around 8 lines of code getting repeated over in many different forms/classes couple of times. So as of now, i could find 4 classes/forms which are repeating this above code, so thus i could save around 32 lines altogether.

I do agree that there is still alot room for improvement. How ever at the moment i can not foresee those improvements. It would kind and great of you as a reader to suggest me those improvements.

My next concentration would be to refactor the event handlers for KeyDown so that i can minimize the implementation code. May be i shall add a base class to all of those classes which has a virtual method having common code and in the derived i invoke first base and then implement few more code.

Thanks and Happy Coding 🙂

Update: As part of this refactoring, today i found out few more places in my code base which could reuse this common code, such a way now i could save around 60 lines of raw code getting repeated to just few lines. I am finally happy and satisfied 🙂

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s