Some time ago I've read a great article Context Help Made Easy by Tom Clement. The article can be found here.
Tom's idea is great - rather than putting the HelpProvider on each of your application's forms, you keep the information about the topic mapping in a single XML file. There is also an additional message filter executing in the application context which traps F1 presses, reads the provided topic mapping and redirects the help provider to the specific topic.
The most interesing part of Tom's article is the idea of instrumenting the execution and providing a dialog form which is used to provide topic mapping for current context. It is then possible to train someone to use this feature to map user interface contexts to help topics - the mapping is provided while the application is actually running and not in the design time.
Below is the brief description of differences between Tom's and my implementation.
- in Tom's implementation the Main routine of the application has to be augmented with the message filter injection. In my implementation - a custom component is used so that the only thing you have to do is to put the component on the main form of the appliaction
- in Tom's implementation all user interface controls have to implement the mapping interface. I belive that this is not necessary - help topics can be mapped to a context defined by the FormClassName/Control1Name/Control2Name/Control3Name/..../ControlNName built directly from the runtime information (parent-child relation of controls and controls' names)
- From the point of view of someone who actually maps controls to help topics the hierarchical view is much more natural than the flat ListView. In my implementation, topics which are not mapped are shown as red and topics already mapped - as black (please forgive localized labels, feel free to customize it)
- in my implementation the XML file used to store the topic mapping, help.mapping, can be stored as a resource in any application module. If the file is found in the same directory as the main executable file of the application - it is used as a primary source of the topic mapping.
- in Tom's implementation the ability to provide topic mapping is available always by pressing Ctrl+F1 instead of F1 which just shows the help topic. In my implementation you have to provide a special runtime commandline parameter, helpbuilder, to be able to use the map builder
- the Control.FromHandle method used by Tom to retrieve the control instance from the window handle does not always work as expected. For example - when a ComboBox in DropDown mode is active then the message filter gets not the handle of the combo but rather the handle of the combo's internal textbox. The Control.FromHandle does not work then because the combo's internal textbox is not a control instantiated by the .NET. In my implementation when Control.FromHandle fails, the application tries to retrieve the control's parent control and repeats the Control.FromHandle. This correctly resolves the ComboBox (and other composite controls) issue.
In order to make your application compatible with my library you have to:
- recompile the library from the provided source
- put the HelpComponent on the main form of your application
- run the application with helpprovider commandline parameter
- use Ctrl+F1 to map help topics to controls. Remember about the hierarchy - you do not have to provide topics for all controls, it is sufficient to provide the topic for a container control and all its child controls inherit the mapping.
- remember to provide a help file name (must be a *.chm file located beside the application main executable)
- when the mapping is complete, include the help.mapping file stored beside the application main executable as an embedded resource in one of assemblies
- remove the help.mapping file located beside the application main executable
- rebuild the application
From now, the included resource is used as a primary help mapping provider. If you need to customize it further, repeat above process starting with the 3rd step (the included resource will be copied as a file beside the application main executable and used as a primary help mapping provider.
Download the source code here. You are free to use and modify it without any explicit permission.
Please leave a comment if you find this small library usable.
Edit: Please also take a look at the second part of this article: http://netpl.blogspot.com/2007/08/context-help-made-easy-reloaded.html