Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Refactoring Hooking and Unhooking events TIP

, 4 Jan 2012 LGPL3
Rate this:
Please Sign up or sign in to vote.
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

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 HookEvents()
{
    IEnumerable < Controls > allControls =
            CollectUIControlsHelper.Instance.CollectAllControlsDeep(this);

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

UnHooking events (Part of Dispose call):
public void UnHookEvents()
{
    IEnumerable < Controls > allControls =
           CollectUIControlsHelper.Instance.CollectAllControlsDeep(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 CollectAllControlsDeel(this). And does the opposite in UnhookEvents. 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 HookEvents(Control control,
             Action<object,KeyEventArgs> eventHandler)
    {
        IEnumerable < Control > allControls =
          CollectUIControlsHelper.Instance.CollectAllControlsDeep(control);

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

    public void UnHookEvents(Control control,
            Action<object, KeyEventArgs> eventHandler)
    {
        IEnumerable < Control > allControls =
          CollectUIControlsHelper.Instance.CollectAllControlsDeep(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 eventhandler 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 commong code and in the derived i invoke first base and then implement few more code.

Thanks and Happy Coding :)


Filed under: C#, CodeProject, Dotnet Tagged: .NET, bing, blog, blogger, C#, codeproject, Dotnet, google, tips

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

Share

About the Author

zenwalker1985
Software Developer (Senior) Siemens
India India
A .net developer since 4+ years, wild, curious and adventurous nerd.
 
Loves Trekking/Hiking, animals and nature.
 
A FOSS/Linux maniac by default Wink | ;)
 
An MVP aspirant and loves blogging -> https://adventurouszen.wordpress.com/
Follow on   Twitter

Comments and Discussions

 
QuestionArchitecture ideas Pinmemberneil.hall4-Jan-12 17:34 
AnswerRe: Architecture ideas Pinmemberzenwalker19854-Jan-12 18:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.141015.1 | Last Updated 4 Jan 2012
Article Copyright 2012 by zenwalker1985
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid