views:

746

answers:

2

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

A: 

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.

Binary Worrier
Well it just doesn't feel like a 'clean' way to do this - the code would have to ‘walk’ the control hierarchy. Your delegate suggestion would definitely though work, thanks :)
mouters
A: 

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.

Groo
Actually I’ve already read this article and have gone so far as to implement the ProcessKeyPreview method (btw the help context needs to come direct from the database so the window help file format isn’t an option).
mouters
I then remembered that I needed to provide help using the question mark button (usually top right of a form) where you can click a control and again get context help. After some research this morning i came across the HelpRequested event which seems more appropriate than trapping the F1 key since the .Net framework is exposing this event specifically for developer to implement a help system.All the same get suggestion – thanks :)
mouters
Yes, that is the suggested solution, but if you want to fire a "global" event, then you can fire it from WndProc yourself, and have a single event handler.
Groo