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 a KeyDown
event 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, it's 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 nothing great. But the annoying thing or the 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 these 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, thus I could save around 32 lines altogether.
I do agree that there is still a lot of room for improvement. However, at the moment, I cannot foresee those improvements. It would be kind and great of you as a reader to suggest those improvements.
My next concentration would be to refactor the event handlers for KeyDown
so that I can minimize the implementation code. Maybe I will add a base class to all of those classes which have a virtual
method having common code and in the derived, I invoke first base and then implement a little more code.
Thanks and happy coding!
Filed under: C#, CodeProject, Dotnet
Tagged: .NET, bing, blog, blogger, C#, codeproject, Dotnet, google, tips