Global event handler for all controls for User Help

3.5k views Asked by At

HI, I'm extending a windows application written in C# to provide help to the user (in the context of the focused control) when they hit the F1 key.

What I’d like to do is make use of the Control.HelpRequested event but I’m not sure how to extend all the controls to handle this event. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.helprequested.aspx

It’s not really feasible to update each control “by hand” to handle this event and I really don’t like the idea of looping through all the controls in a form (as the form opens) to associate the event handler.

Is there a neat way to extend all controls of a form to handle a specific event?

This is just made up but i almost feel like i should be able to write something like this

[HandleEvent Control.HelpRequested, ApplyTo Typeof(Control)]
void MyEventHandler(object sender, EventArgs e)
{
// code to handle event...
}

Any suggestions or perhaps ideas on a different approach are much appreciated - Thanks

3

There are 3 answers

3
vgru On BEST ANSWER

This example (http://www.codeproject.com/KB/cs/ContextHelpMadeEasy.aspx) shows how to trap the F1 key in WndProc and then show the help from one method only.

The idea in that article is to implement an interface exposing control's ID and then show context help based on that id. The F1 handler then checks if your control implements that interface, and if not, then it check's the control's parent until it finds an implementation of that interface.

But an even simpler approach (if you don't want to add an ID to each control) is to modify the F1 handler to show context help based on a static type dictionary (e.g. Dictionary), which would contain Topic IDs for every supported control. So, whenever you need to associate a topic with a specified control, you would update the dictionary.

Again, it would be wiser to add more abstraction to this approach by adding some sort of a provider (delegate or interface) to that dictionary. For example, you might need additional logic to show topics based on control's type, name, or some other property.

1
Binary Worrier On

I really don’t like the idea of looping through all the controls in a form (as the form opens) to associate the event handler.

Can I ask why not?

You could write a function that takes a delegate and a list of types as an arguement, which will have exactly the same effect as your "wished for" HandleEvent attribute.

0
Reza Aghaei On

The HelpRequested supports bubble up mechanism. It fires for your active control and if you don't handle the event and not set Handled property of its event arg to true, then it bubbles up to the parent control hierarchy up to form.

So it's enough to handle your HelpRequested of your form and then, you can decide about the help you want to show, based on active control of the form or its parent hierarchy.

Example

If you handle HelpRequested event of the form like below, then when you press F1 a message box will pop up and show name of active control:

private void Form1_HelpRequested(object sender, HelpEventArgs hlpevent)
{
    var c = this.ActiveControl;
    if(c!=null)
        MessageBox.Show(c.Name);
}