News · Meetings · Jobs · Downloads · Universal Thread articles · Web articles · Conference coverages · Consultants · Blogs · FAQ · User groups · Photos · Videos

Wiki-based help system

Eric Moreau, Moer Inc.
Eric Moreau is an independent contractor. He holds the Microsoft Certified Solution Developer (MCSD) certification and is also a Visual Developer - Visual Basic MVP. He is mainly programming client/server applications using VB/VB.Net and MS SQL Server (and all the stuff surrounding it) particularly in the financial industry. He works with VB since version 4 and teaches it since version 5. He is a member of the Montreal Visual Studio User Group (www.guvsm.net) where he gives some sessions. He is also a speaker at the DevTeach conferences since its beginning in 2003.

What are the fun parts of our job? If you are a regular reader of my articles, you will surely answer something like writing code, debugging an existing application (yes I like it when I find that one little bug that was so obvious now that we know what it is), building the architecture of the next application, trying newest versions of developers’ tools, and so on.

What do you hate the most? Well your answer may vary but for most of you it would likely be something around the documentation! Am I right?

A long time ago (back in December 2004), I showed you how to build a real help system based on help files that you have to build yourself and link your application to (see Creating help files and linking them to a VB application). Have you built many since that time even if you know how to do it now?

If your users are like mine, they always find that the help files, if you decide to build any, are never complete or up-to-date. This is often because documentation and/or help files are the last thing done in a project and very often you don’t do it because you have to jump on something else.

This month, my column will show you how to save time on the creating help files and ensure that users cannot blame you if those files are not updated. Why not let the users create their own help system and maintain it? This is a very good idea that one of my friend (thanks Nicolas) told me lately. A kind of wiki but still sensitive to the form the users are on.

Because I am using the RichTextBox control, rich text formatting and images are natively supported. Users are also able to copy existing text from an application such as Microsoft Word directly to your RichTextBox control. I am sure they will like it.

I also want the help to be context-sensitive but I don’t want to go to deep. I only want to detect on which I am and display the help related to this form. I don’t want to have a big endless scrolling textbox that user will complain that it is too long.

The basic form

I will start by showing you the form that will be used by users to enter the text as shown in figure 1.

Figure 1: The help form

It is composed of only 3 controls: a ToolStrip, a RichTextBox control, and a checkbox.

The toolbar let the user do usual task such as clear the current text, save the text, cut, copy, paste, change the font of the selected text, and change the color of the selected text. When I have added the ToolStrip control to the form, I used the smart tag actions to insert standard items as a start point. I removed a couple of unwanted buttons (open, print, help) and added a few more (font and font color).

The second control on this form is the RichTextBox control which is the easiest way to let user have a real text editor that allows great features such as pasting content from Microsoft Word.

The last control is a CheckBox that will let the user to use the help form outside the MDIParent form. This is simply done by setting the MdiParent property of the form to Nothing. This is really simple but with more and more users having more than one screen attached to their PC, users start to ask to be able to detach some of the forms from the MDIParent container.

If you need details on how to work with the ToolStrip control, refer to an article I have written on that topic in May 2006 - The Strippers’ club. If you need details on the Font dialog and/or the Color dialog, refer to another article I have written in June 2003 - Common Dialogs.

Persisting data

For this demo, the data entered by user as the help text is persisted into a dataset which is saved as a XML file when the application is closing using the WriteXml method of the dataset object.

This is one thing you will surely want to improve in order to correctly support concurrent users.

I always prefer to save that kind of data into a real database but it would have been harder for you to quickly try this demo application.

When the fMDIParent form loads, the OpenHelpDataset method opens the XML file and loads it into a dataset object or creates a new dataset if the file does not exist:

Private Sub OpenHelpDataset()
    If Not IO.File.Exists("Help.xml") Then
        mHelpDataset = New DataSet

        Dim dt As New DataTable
        With dt
            .TableName = "HelpTable"
            With .Columns
                .Add("Code", GetType(String))
                .Add("HelpText", GetType(String))
            End With
        End With
        mHelpDataset.DataSetName = "HelpDataset"
        mHelpDataset = New DataSet
    End If
End Sub
When the fMDIParent form is closing, the SaveHelpDataset method is called to save the data entered by the user into the XML file:
Private Sub SaveHelpDataset()
End Sub
The help form has methods to move data from (see the LoadFormData method) and to (see the SaveData method) this dataset. You will notice that the RTF property of the RichTextBox control is the one used to persist all the formatting. If you use the Text property, all formatting would be lost. You also need to ensure that your field containing the help text into the database is large enough. If you are using Microsoft SQL Server 2005 (or later), you can use the VarChar(MAX) data type.

Integrating the help form into a MDI project

Now that we have our help form almost ready, it is time to integrate it into an application.

You could add a button on each form that creates a new instance of the help form but I will use another method. I will suppose that your application is a MDI application and that your main form has a toolbar and/or a menu (I don’t think that I am off the track here!). In my demo application, I have added a MDI parent which already comes with a menu and a toolbar that I have trimmed a bit.

When the help button or menu item is selected, you need to find which form is currently active in order to display the help that goes with this form. So detecting the active is the first task to do. So I try to find the ActiveMdiChild name, if it is not working, I try the ActiveForm (which would be a standalone form). If neither works, I suppose that no forms are currently opened and force the main help to appear. It is really important to catch exception here because nothing guarantees that a form exists:

Dim strCurrentForm As String = String.Empty
Dim strFormTitle As String = String.Empty

'Try to find a child form
    strCurrentForm = ActiveMdiChild.Name
    strFormTitle = ActiveMdiChild.Text
Catch ex As Exception
    strCurrentForm = String.Empty
End Try

'Try with the active form
If strCurrentForm.Length = 0 Then
        strCurrentForm = ActiveForm.Name
        strFormTitle = ActiveForm.Text
    Catch ex As Exception
        strCurrentForm = String.Empty
    End Try
End If

'No forms - We are surely on the MDI parent
If strCurrentForm.Length = 0 Then
    strCurrentForm = "Main"
    strFormTitle = "Main form"
End If
Now that we know what is the current form is (which is the key to retrieve the correct help topic), we can display the help form:
Dim f As New fHelp
f.MdiParent = Me
f.LoadHelpForm(strCurrentForm, strFormTitle, mHelpDataset)
Notice that we call the LoadHelpForm method of the fHelp form which is responsible of loading the data from the dataset into the controls.

Figure 2: The demo application in action

Extending this system

I am sure you will have many ideas to enhance this feature even more.

You could start by providing a richer ToolStrip control for editing. Before doing it all by yourself, have a look at what Richard Parsons has posted on the CodeProject web site. It is a wrapper component containing a Toolbar control and a RichTextBox control written in C# that you can plug into your application.

If you build a small table containing the hierarchy of your forms, you could easily show a treeview to let the user navigate between the different help pages.

It would also be nice to be able to print those topics. With the hierarchy of the previous idea, it could be possible to create a table of content and print it in a logical order. If you are interested to try something like this, have a look at Aspose.Words which is a commercial component (meaning not free) that could be very helpful if you want something which is more robust to use then Microsoft Word automation.


Now the pressure is on the users to keep the help system ... helpful and up-to-date. I am sure they will appreciate the fact that they can put their own wording into what THEY used. After all, the help is built for them, why not by them?

I hope you appreciated the topic and see you next month.

Source code

More articles from this author

1.A custom MessageBoxJanuary 2006
2.A Folder Browser dialog (in Windows Forms)April 2003
3.Adding plug-ins to your applicationsAugust 2005
4.An Action List componentAugust 2007
5.Applications Settings in VB.NetMay 2003
6.AppSettings revisitedMarch 2007
7.Code diagnostic (an article on tracing and debugging)November 2003
8.Colors of disabled controlsJuly 2005
9.ComboBoxes in Windows Forms DataGridsJanuary 2003
10.Common dialogsJune 2003
11.Compression in the .Net Framework 2.0February 2007
12.Creating help files and linking them to a VB applicationDecember 2004
13.Creating your own Windows Custom ControlMarch 2003
14.Crystal Reports – Part IIOctober 2006
15.Drag and Drop in VB.NetFebruary 2004
16.Embedding a font into an applicationFebruary 2008
17.Extender providersOctober 2004
18.Extending the My namespaceJuly 2007
19.Feeding Crystal Reports from your applicationSeptember 2006
20.Folders synchronization using the System.IO namespaceMarch 2006
21.Fun with MDI formsSeptember 2003
22.Handling an offline featureOctober 2005
23.Interfacing the Windows Task SchedulerAugust 2004
24.LocalizationJuly 2004
25.MARS and Asynchronous ADO.NetNovember 2006
26.Microsoft Visual Basic Power Packs 3.0April 2008
27.Monitoring your applications using custom performance countersFebruary 2006
28.Multi columns ComboBoxFebruary 2005
29.My thoughts on LINQMay 2007
30.Object Serialization in VB.NetJuly 2003
31.Running assemblies from a shared folderApril 2004
32.Scrolling textDecember 2005
33.Setting a master/detail relationship between two ComboBoxesJanuary 2007
34.Setting Windows default printerMarch 2005
35.Strings, Strings, StringsAugust 2006
36.The (incomplete) TabControlMay 2004
37.The BackgroundWorker componentDecember 2006
38.The Clipboard classAugust 2003
39.The DateTimePicker controlJanuary 2005
40.The ErrorProvider Control (in Windows Forms)February 2003
41.The FileSystemWatcher componentApril 2005
42.The My NamespaceJune 2007
43.The NotifyIcon classJanuary 2004
44.The Process componentDecember 2003
45.The PropertyGrid controlJune 2004
46.The StatusBar controlSeptember 2004
47.The Strippers’ clubMay 2006
48.The TextBox and the MaskedTextbox controlsJune 2006
49.The Toolbar controlNovember 2004
50.The Treeview controlApril 2006
51.The Treeview control - Part IIJuly 2006
52.The WebBrowser controlApril 2007
53.This month's profile: Eric MoreauJune 2001
54.Using MS-Agent in a VB.Net applicationJune 2005
55.Using Reflection to spy forms’ contentSeptember 2005
56.Using System.Net.MailSeptember 2007
57.Using the ConnectionStrings section of the configuration fileApril 2009
58.Using the registry from a VB.Net applicationOctober 2003
59.Using The WebRequest object to retrieve Yahoo stock quotesMarch 2004
60.VB.Net and the Google APIMay 2005
61.Visual Basic and VB.Net FAQsJuly 2001
62.Visual Basic and VB.Net FAQsJune 2001
63.What’s new in VS2005 for Windows Forms Developers?November 2005

Copyright © 1993 - 2014 Level Extreme Inc., All Rights Reserved · Telephone: 506-783-9007 Email: info@universalthread.com · Privacy & Security · Copyright · Terms & Conditions