Click here to Skip to main content
Click here to Skip to main content

Refactoring Hooking and Unhooking events TIP

By , 4 Jan 2012
 

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)

About the Author

zenwalker1985
Software Developer (Senior) Siemens
India India
Member
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/

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionArchitecture ideasmemberneil.hall4 Jan '12 - 17:34 
AnswerRe: Architecture ideasmemberzenwalker19854 Jan '12 - 18:16 

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 4 Jan 2012
Article Copyright 2012 by zenwalker1985
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid