How to Make Help File With C#


Using TreeView control and XML file to create a help file.

AppHelp.JPG

Would you like to add a help file to your application? I think it is easy to do with C#.

This is an uncomplicated trial to add a help to your project; it is easy to create.

I wrote an article before about the new ActiveX control (MKGrid), and wrote its help using Microsoft HTML Workshop and it was necessary to write more than sixty HTML files because every item of my help needs one file, and that was so boring!

I think It's probably a good idea to make my help file by myself, this trial will not be costing me more than a TreeView control and XML file.

Now, this article to create a help for my ActiveX MKGrid, you need little code to create a help using the TreeView control and populate it with a XML file.

Step 1:

Write the XML file:

Use "MS FrontPage" or "MS Word" or any word processor to write XML file for the help; see my sample MyHelp1.xml and MyHelp2.xml in the folder (DataFiles) which I wrote for the MKGrid control.

Step 2:

Add the following reference to your code:

Using System.Xml;

Step 3:

Design the help form.

My project has three forms.

frmMain form: this form is an example of the main form of your project.

I used this form to show the ActiveX control MKGrid which I wrote help for it, you can add MKGrid control to the ToolBox as (COM Components) from (MyActiveX) folder.

frmHelp1 form: my article about this form; this form has the following controls:

TextBox (its name: txtHelp, to display help)

Button (its name: btnClose, to close help form)

TabControl (its name:tabHelp)

This tab has two pages: ContentsPage, IndexPage

TreeView (its name: tvHelp) put on (ContentsPage)

ComboBox (its name: cmbHeading, its type: Simple) put on (IndexPage)

Label (its name: lblHint, its text: Type Keyword to find) put on (IndexPage)

Button (its name: btnDisplay) put on (IndexPage)

frmHelp2 form: has the same controls of the frmHelp1 form.

Please add the following variables to frmHelp1 and frmHelp2:

private string MyHelpFile;
private XmlDocument XmlDoc = new XmlDocument();

Add the following code after InitializeComponent():

//init TreeView
tvHelp.Nodes.Clear();
tvHelp.ImageList = IconImages;
tabHelp.SelectedTab = ContentsPage;
cmbHeading.Items.Clear();


Add the following code to the Form_Load procedure:

in frmHelp1:
MyHelpFile = Application.StartupPath + "\DataFiles\" + "MyHelp1.xml"
in frmHelp2:
MyHelpFile = Application.StartupPath + "\DataFiles\" + "MyHelp2.xml"
XmlDoc.Load(MyHelpFile);
LoadTreeView();

Code for frmHelp1:

We shall set a nodes name to tvHelp TreeView control by the following procedure:

 private void LoadTreeView()
 {
     XmlNodeList xNodeList;
     string strNode;

     try
     {
         // set root node of TreeView.
         tvHelp.Nodes.Add("Application Help");
         tvHelp.Nodes[0].Tag = "AppHelp";
         tvHelp.Nodes[0].ImageIndex = 0;
         tvHelp.Nodes[0].SelectedImageIndex = 0;

         // set Introduction node to TreeView.
         tvHelp.Nodes[0].Nodes.Add("Introduction");
         tvHelp.Nodes[0].Nodes[0].Tag = "Introduction";
         tvHelp.Nodes[0].Nodes[0].ImageIndex = 2;
         tvHelp.Nodes[0].Nodes[0].SelectedImageIndex = 2;

         // set Methods node to TreeView.
         tvHelp.Nodes[0].Nodes.Add("Methods");
         tvHelp.Nodes[0].Nodes[1].Tag = "Methods";
         tvHelp.Nodes[0].Nodes[1].ImageIndex = 0;
         tvHelp.Nodes[0].Nodes[1].SelectedImageIndex = 0;

         // set Properties node to TreeView.
         tvHelp.Nodes[0].Nodes.Add("Properties");
         tvHelp.Nodes[0].Nodes[2].Tag = "Properties";
         tvHelp.Nodes[0].Nodes[2].ImageIndex = 0;
         tvHelp.Nodes[0].Nodes[2].SelectedImageIndex = 0;

         // set all Method nodes to TreeView.
         xNodeList = XmlDoc.SelectNodes("//Method");
         foreach (XmlNode xNode in xNodeList)
         {
             strNode = xNode.SelectSingleNode("title").InnerText;
             tvHelp.Nodes[0].Nodes[1].Nodes.Add(strNode);
             // add Method title to ComboBox;
             cmbHeading.Items.Add(strNode);
         }
         // set Method nodes image
         for (int i = 0; i < tvHelp.Nodes[0].Nodes[1].Nodes.Count; i++)
         {
             tvHelp.Nodes[0].Nodes[1].Nodes[i].ImageIndex = 2;
             tvHelp.Nodes[0].Nodes[1].Nodes[i].SelectedImageIndex = 2;
         }

         // set all Property nodes to TreeView.
         xNodeList = XmlDoc.SelectNodes("//Property");
         foreach (XmlNode xNode in xNodeList)
         {
             strNode = xNode.SelectSingleNode("title").InnerText;
             tvHelp.Nodes[0].Nodes[2].Nodes.Add(strNode);
             // add Property title to ComboBox;
             cmbHeading.Items.Add(strNode);
         }

         // set Property nodes image
         for (int i = 0; i < tvHelp.Nodes[0].Nodes[2].Nodes.Count; i++)
         {
             tvHelp.Nodes[0].Nodes[2].Nodes[i].ImageIndex = 2;
             tvHelp.Nodes[0].Nodes[2].Nodes[i].SelectedImageIndex = 2;
         }

         cmbHeading.SelectedIndex = 0;
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
 }

How to read help when clicking any item? The following procedure can do the job:

private void DisplayHelp(string strName)
{
    XmlNode xNode;
    string strHelp;
    // if user click any title
    xNode = XmlDoc.SelectSingleNode("//*[title='" + strName + "']");
    strHelp = xNode.InnerText;
    txtHelp.Text = strHelp;
}

We need three events to display the help when the tvHelp node is clicked, when btnDisplay is clicked or when any item of the cmbHeading ComboBox is clicked.

Please read the code of tvHelp_AfterSelect (), btnDisplay_Click() and cmbHeading_MouseDoubleClick () in my project.

If you don't like the code of frmHelp1 form and MyHelp1.xml file, you can use the following code of frmHelp2 form and MyHelp2.xml file

Code for frmHelp2:

We shall read nodes name from the MyHelp2.xml file to set it to tvHelp TreeView control, we do this by two procedures LoadHeading() and
AddNextNodes():

 private void LoadHeading()
 {
     // Add first node (the Root)
     tvHelp.Nodes.Add(new TreeNode(XmlDoc.DocumentElement.Name));
     TreeNode tNode = new TreeNode();
     tNode = (TreeNode)tvHelp.Nodes[0];
     // Add next nodes
     AddNextNodes(XmlDoc.DocumentElement, tNode);
 }

 private void AddNextNodes(XmlNode xmlNode, TreeNode treeNode)
 {
     XmlNode xNode;
     TreeNode tNode;
     XmlNodeList nodeList;

     if (xmlNode.HasChildNodes) //The current node has children
     {
         nodeList = xmlNode.ChildNodes;
         // Set all child nodes
         for (int i = 0; i <= nodeList.Count - 1; i++)
         {
             xNode = xmlNode.ChildNodes[i];
             // Get the name of node (we want set the head of help item)
             if (xNode.NodeType == XmlNodeType.Element)
             {
                 // Add child nodes to TreeView
                 treeNode.Nodes.Add(new TreeNode(xNode.Name));
                 // Add node name to ComboBox
                 cmbHeading.Items.Add(xNode.Name);

                 cmbHeading.SelectedIndex = 0;
                 tNode = treeNode.Nodes[i];
                 // Add next child nodes if any
                 AddNextNodes(xNode, tNode);
                 // Set image to the node
                 string strName = xNode.Name;
                 switch (strName)
                 {
                     case "ApplicationHelp": // Heading
                         tNode.ImageIndex = 0;
                         tNode.SelectedImageIndex = 1;
                         break;
                     case "Methods": // Heading
                         tNode.ImageIndex = 0;
                         tNode.SelectedImageIndex = 1;
                         break;
                     case "Properties": // Heading
                         tNode.ImageIndex = 0;
                         tNode.SelectedImageIndex = 1;
                         break;
                     default: // other nodes (Pages)
                         tNode.ImageIndex = 2;
                         tNode.SelectedImageIndex = 2;
                         break;
                 }
             }
         }
     }
     // We shall Remove Introduction, Methods, Properties from ComboBox:
     // We do not want to display the (Introduction) in Index
     cmbHeading.Items.Remove("Introduction");
     // (Methods) hasn't any help
     cmbHeading.Items.Remove("Methods");
     // (Properties) hasn't any help
     cmbHeading.Items.Remove("Properties");
 }

The Following procedure can read help:

private void ReadHelp(string strNode)
{
    XmlTextReader textReader = null;
    string s = "";
    try

    {
        textReader = new XmlTextReader(MyHelpFile);
        while (textReader.Read())
        {
            if (textReader.Name == strNode)
            {
                s = textReader.ReadString();
                txtHelp.Text = s;
            }

        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        if (textReader.EOF)
            textReader.Close();
    }
}

Remarks:

When extract the files EasyHelp_ C#.zip you can find:

C# (2008) project with three forms.

The folder (MyActiveX) includes KGrid.ocx ActiveX control.

The folder (DataFiles) includes MyMarket.mdb, MyHelp1.xml and MyHelp2.xml.

The folder (Icons) includes three icons.

I hope this article is useful. If you have any idea, please tell me.