Monday, July 16, 2007

Context Help Made Easy - Revisited

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

Tuesday, July 3, 2007

Tiny ASP.NET Ajax Framework Contest Continued...

Few days ago we've held a tiny contest of three ASP.NET Ajax frameworks. This time, three more contestants await to be compared:

These three above were chosen because the integration of an existing application is as simple as placing a single Ajax Manager on a web form - few other frameworks (and here) were rejected because they are either dead now, force you to use specific set of components or rely on writing client-side javascript code.

The result chart is available here:

  • ComfortASP.NET has a terrible requests-per-second ratio. It served only 35 (!) requests per second, while sending 6 and receiving 83 MB of data
  • Anthem.NET was able to process 133 request per second, sending 6 and receving 121 MB of data
  • Telerik's RAD Ajax did 292 requests per second, sending 7 and receiving 172 MB (!) of data

Gathering all results together, we had 2 non-Ajax contestants: pure Web.Forms application, Javascript version of it and 6 Ajax frameworks: Microsoft's ASP.NET AJAX, Ajaxium, VisualWebGUI, ComfortASP.NET, Anthem.NET and Telerik's RAD Ajax.

Regarding requests-per-second we have following results:

 

 

requests-per-second

reference

VWG

422

198,1220657

Javascript

400

187,7934272

Telerik

292

137,0892019

ASP.NET AJAX

222

104,2253521

Web.Forms

213

100

Anthem

133

62,44131455

Ajaxium

111

52,11267606

Comfort

35

16,43192488

 

Regarding number-of-bytes-sent we have following results:

 

 

sent data

reference

Javascript

1938800

24,23560589

VWG

2066800

25,83564589

Ajaxium

5029800

62,87407185

ASP.NET AJAX

5600600

70,00925023

Comfort

5880400

73,50683767

Anthem

6161400

77,01942549

Telerik

7293200

91,16727918

Web.Forms

7999800

100

 

Regarding number-of-bytes-received we have following results:

 

 

received data

reference

VWG

23348807

29,11700146

Javascript

37121000

46,29153905

Ajaxium

47756301

59,55423272

Web.Forms

80189600

100

Comfort

83742600

104,4307491

Anthem

121547800

151,575516

ASP.NET AJAX

129531800

161,5319194

Telerik

172294800

214,8592835

 

Few comments:

  • the overall winner is VWG, however the application had to be completely rewritten in order to run under this framework
  • the javascript version did not win (even in the bytes-received test!) and though this may seem surprising, it is caused by the script size
  • the Ajaxium, Anthem and Comfort reduce the requests-per-second ratio singificantly. The latter two are able to correctly handle dynamic, non-ajax content sent to the browser
  • regarding the requests-per-second, Telerik is significantly better than ASP.NET AJAX, however it downloads huge amout of data comparing to all other frameworks

Please feel free to study these resulsts and pick up your own winner. Thanks again to Krzysiek Owczarek for contributing to this contest.