Click here to Skip to main content
13,288,869 members (66,636 online)
Click here to Skip to main content
Add your own
alternative version


273 bookmarked
Posted 2 Feb 2007

Context Help Made Easy

, 2 Feb 2007
Rate this:
Please Sign up or sign in to vote.
This article introduces a new way of instrumenting your code that enables help authors associate help topics with the application’s visual contexts at any time - even post-compilation – and to do so using the application’s user interface without the involvement of the developer.



Most application developers have been through it. During the later stages of a project, you find yourself spending time working with an HTML Help author to connect the screens and dialogs of your application to context sensitive help.

This article introduces a way to instrument your code that enables help authors to associate help topics with the application's visual contexts at any time - even post-compilation – and to do so using the application's user interface without the involvement of the developer. There is no need for the help author to manually edit any files or have knowledge of any internals.

The Context Mapping dialog box


Like my earlier articles [^], this one steps you through the code writing process, displaying code snippets for each change. I'm sure that readers will have many valuable comments, criticisms, and suggestions to offer. You are encouraged to do so in the discussion section at the bottom of the article. I will do my best to incorporate your thoughts in the next revision of the article - but even if I'm a lazy bum and don't get around to it, you will be sharing your perceptions and ideas with others in the community.

What is Context?

When you're running an application (as in life), you are always in multiple contexts at any given moment. For example, if the focus is in a particular TextBox control, the context can be all of the following: the TextBox, a TabPage containing the TextBox, the Tab control containing the TabPage, the dialog box containing the TabPage, and the application itself. It is up to the help author to decide which of these contexts should have an associated help topic.

The general approach many applications take when launching Context Sensitive Help is to start with the control with the focus and check to see if it has an associated help topic. If so, the application launches the topic, and if not, it moves outward (i.e., up the parent chain) to the containing control and repeats the process.

Implementing F1 Help

We'll start by implementing a system for displaying an associated topic when the F1 key is pressed, by using a ContextID to topic mapping that will be stored in an XML configuration file. After this is working, we'll get to adding the feature that enables help authors to edit these mappings from inside the application UI. Click on this link to skip to the fun part. :)

The IContextHelp Interface

The first step is to create an Interface (IContextHelp) that you can add to the various controls in your project. This interface identifies controls that are candidates for acting as a context for help, and provides a unique string identifier (ContextID) to identify the context.

public interface IContextHelp
  string ContextHelpID { get; }

Since such controls are typically derived from UserControl, we can simplify things further by creating a UserControlEx that implements the interface. To use this, derive your user controls from UserControlEx instead of UserControl. In the default implementation, the ContextID for the control is the fully qualified class name of the control.

public virtual string ContextHelpID {get{return this.GetType().FullName;}}

Similarly, we create a FormEx that implements IContextHelp in the same way. When you define a form in your application, change it to derive from FormEx instead of Form.

If you want to provide context help for standard Windows or third party controls, you can do so easily by deriving new controls and adding the interface. For example:

// PanelEx is like a Panel, except that it implements IContextHelp
public class PanelEx : Panel, IContextHelp
  private string m_sContextID;
  public string ContextHelpID
      if (string.IsNullOrEmpty(m_sContextID))
        return this.Name;
      return m_sContextID;
    set { m_sContextID = value; }

In this case, we use the control's name as the default ID, and permit it to be overridden in case there is a name conflict. In practice, that hasn't been necessary for projects I've worked on.

If you need to provide a context ID for many different standard Windows or third party controls, you should consider implementing an IExtenderProvider as described by Charles Williams [^] in his excellent comment[^] to the original version of this article.

Trapping the F1 Key

You can implement a single handler to trap and respond to the F1 key press throughout your application by adding a message filter to your application, and checking for F1 when the WM_KEYDOWN message is received.

static void Main()
   //add message filter
   MessageFilter oFilter = new MessageFilter();
   // etc.
internal class MessageFilter : IMessageFilter
  #region IMessageFilter Members
  bool IMessageFilter.PreFilterMessage(ref Message m)
     //Use a switch so we can trap other messages in the future.
     switch (m.Msg)
       case 0x100 : // WM_KEYDOWN
         if ((int)m.WParam == (int)Keys.F1)
           return true;
     return false;

Handling the F1 Key

Now that we've taken care of the infrastructure, it's time to show how to handle the F1 key. Later, we'll modify this method to test for the Control key, but for now it looks like this:

public static class HelpUtility
  public static void ProcessHelpRequest(Control ctrContext)

The ShowContextHelp() method travels up the parent chain, looking for a control that:

  1. implements IContextHelp,
  2. has a non-empty IContextHelp.ContextHelpID, and
  3. has a corresponding entry in the mapping XML file.

If one is found, it launches the help viewer to display it. If not, it launches the default topic.

// Process a request to display help
// for the context specified by ctrContext.
public static void ShowContextHelp(Control ctrContext)
  Control ctr = ctrContext;

  string sHTMLFileName = null;
  while (ctr != null)
    // Get the first control in the parent chain
    // with the IContextHelp interface.
    IContextHelp help = GetIContextHelpControl(ctr);
    // If there isn't one, display the default help for the application.
    if (help == null)
    // Check to see if it has a ContextHelpID value.
    if (help.ContextHelpID != null)
      // Check to see if the ID has a mapped HTML file name.
      sHTMLFileName = LookupHTMLHelpPathFromID(help.ContextHelpID);
      if (sHTMLFileName != null && ShowHelp(ctrContext, sHTMLFileName))
    // Get the parent control and repeat.
    ctr = ((Control)help).Parent;
  // Show the default topic.
  ShowHelp(ctrContext, "");

The GetIContextHelpControl() method traverses up the parent chain, looking for an IContextHelp control.

// Get the first control in the parent chain
// (including the control passed in)
// that implements IContextHelp.
private static IContextHelp GetIContextHelpControl(Control ctl)
  while (ctl != null)
    IContextHelp help = ctl as IContextHelp;
    if (help != null)
      return help;
    ctl = ctl.Parent;
  return null;

The ShowHelp() method launches HTML help, displaying the topic specified by


// Display the specified help page.
private static bool ShowHelp(Control ctlContext, string sHTMLHelp)
    if (string.IsNullOrEmpty(sHTMLHelp))
      Help.ShowHelp(ctlContext, HelpUtility.HelpFilePath);
      Help.ShowHelp(ctlContext, HelpUtility.HelpFilePath, 
                    HelpNavigator.Topic, sHTMLHelp);
  catch (ArgumentException)
    // Ideally, we would return false when
    // the HTML file isn't found in the CHM file.
    // Unfortunately, there doesn't seem to be
    // a way to do this without parsing the CHM.  
    return false;
  return true;
// Define this contstant at the top of the file.
private const string mc_sHELPFILE = "ContextHelpMadeEasy.chm";
// Return the path to the CHM file.
private static string HelpFilePath 
    return Path.Combine(System.Windows.Forms.Application.StartupPath, 

Reading the Mapping File

To complete F1 help, we need to implement the LookupHTMLHelpPathFromID() function called from ShowContextHelp(). This method examines the ID to topic mappings, and returns the topic filename if a mapping exists. The mappings are read from the XML configuration file on first access, and cached to avoid reading the file every time a user presses F1. We start by defining a

to hold the mapping cache. In addition, we define a number of constants which represent the mapping file name, and various XML elements and attribute names.

static private StringDictionary ms_sdContextPaths = null;
private const string mc_sMAPPING_FILE_NAME = "HelpContextMapping.Config";
private const string mc_sIDMAP_ELEMENT_NAME = "IDMap";
private const string mc_sCONTEXTID_ELEMENT_NAME = "ContextID";
private const string mc_sID_ATTRIBUTE_NAME = "ID";
private const string mc_sHTMLPATH_ATTRIBUTE_NAME = "HTMLPath";

The MappingFilePath property returns the path to the mapping file, which is assumed to be in the same directory as the application executable.

private static string MappingFilePath 
  get { return Path.Combine(Application.StartupPath, mc_sMAPPING_FILE_NAME); } 

The ContextPaths property implements the cache by reading the mapping file only on the first call.

private static StringDictionary ContextPaths
    if (ms_sdContextPaths == null)
      ms_sdContextPaths = ReadMappingFile();
    return ms_sdContextPaths;

The ReadMappingFile() method creates a StringDictionary and populates it with information read from the XML help mapping configuration file.

// Read the mapping file to create a list of ID to HTML file mappings.
private static StringDictionary ReadMappingFile()
  StringDictionary sdMapping = new StringDictionary();
  XmlDocument docMapping = new XmlDocument();
  if (File.Exists(MappingFilePath) == true)
    try { docMapping.Load(MappingFilePath); }
      MessageBox.Show(string.Format("Could not read help mapping file '{0}'.",
            MappingFilePath), "Context Help Made Easy", MessageBoxButtons.OK,
    XmlNodeList nlMappings = docMapping.SelectNodes("//" + 
    foreach (XmlElement el in nlMappings)
      string sID = el.GetAttribute(mc_sID_ATTRIBUTE_NAME);
      string sPath = el.GetAttribute(mc_sHTMLPATH_ATTRIBUTE_NAME);
      if (sID != "" && sPath != "")
          sdMapping.Add(sID, sPath);
  return sdMapping;

A mapping file looks something like this:

<?xml version="1.0"?>
<ContextID ID="namespace.fsettings" HTMLPath="SettingsTopic.htm" />
<ContextID ID="controlname1" HTMLPath="Control1Topic.htm" />
<ContextID ID="overridenidctl2" HTMLPath="Control2Topic.htm" />

With the cache implemented, the LookupHTMLHelpPathFromID() implementation becomes trivial.

// Given an ID, return the associated HTML Help path
private static string LookupHTMLHelpPathFromID(string sContextID)
  if (ContextPaths.ContainsKey(sContextID))
    return ContextPaths[sContextID];
  return null;

Finally! We're done with the F1 implementation, and we can move on to the really cool part - instrumenting your code to allow help authors implement context sensitive help without your involvement.

Instrumenting the Code - Empowering the Help Author

We now have almost everything we need to disentangle the work of the help author with the work of the developer. With the code as described, the author could manually modify the XML configuration file to add and modify help mappings – if they knew the ContextIDs for each application contexts which they want to provide help for.

The idea here is that with the infrastructure already developed, we can turn the application itself into a context sensitive editor for the configuration file. We'll modify the code so that when a HTML help author navigates to some screen, he or she can click Ctrl-F1 and get a dialog that displays all the available ContextIDs for that screen. The HTML help author can then add or remove a ContextID to HTML filename associations using the dialog, with the resulting association written to the help mapping configuration file. Immediately after clicking OK, they can press F1 and see the context sensitive help appear.

Trapping Ctrl-F1

We can modify the ProcessHelpRequest() method described above by adding a check for the Control key as follows:

public static void ProcessHelpRequest(Control ctrContext)
  if (Control.ModifierKeys == Keys.Control)

In practice, you will probably want to put in an additional test to prevent end-users from getting this dialog if they accidentally hit Ctrl-F1. In my implementation, the test for the control key is ANDed with a registry check for a key value that enables this feature. You can, of course, check the application configuration file or anything else that could uniquely identify a help author.

Displaying the Mapping Dialog

Now, if the Control key is pressed when the WM_KEYDOWN message is handled, instead of displaying help for the specified control, we call the ShowHelpMappingDialog() method.

// Traverse the parent control chain looking for controls that implement the
// IContextHelp interface.  For each one found, add it to the list of available
// contexts.  Include the associated HTML path if it's define
// Finally, show the dialog for the help author to edit the mappings.
public static void ShowHelpMappingDialog(Control ctrContext)
  IContextHelp help = GetIContextHelpControl(ctrContext);
  List<ContextIDHTMLPathMap> alContextPaths = new List<ContextIDHTMLPathMap>();
  // Create a list of contexts starting with the current help context
  // and moving up the parent chain.
  while (help != null)
    string sContextID = help.ContextHelpID;
    if (sContextID != null)
      string sHTMLHelpPath = LookupHTMLHelpPathFromID(sContextID);
      alContextPaths.Add(new ContextIDHTMLPathMap(sContextID, sHTMLHelpPath));
    help = GetIContextHelpControl(((Control)help).Parent);
  // Pop up the mapping dialog. If it returns true, this means a change was made
  // so we rewrite the XML mapping file with the new information.
  if (FHelpMappingDialog.ShowHelpWriterHelper(alContextPaths) == true)
    foreach (ContextIDHTMLPathMap pathMap in alContextPaths)
      if (!string.IsNullOrEmpty(pathMap.ContextID))
        if (!string.IsNullOrEmpty(pathMap.HTMLPath))
          ContextPaths[pathMap.ContextID] = pathMap.HTMLPath;
          if (ContextPaths.ContainsKey(pathMap.ContextID))

The mapping dialog opened by calling FHelpMappingDialog.ShowHelpWriterHelper() is discussed below. It basically acts as an editor for the list of ContextIDHTMLPathMap structures.

The ContextIDHTMLPathMap structure containing two strings and a constructor:

// Utility class for maintaining relationship between context Id and path.
public class ContextIDHTMLPathMap
  public string ContextID;
  public string HTMLPath;
  public ContextIDHTMLPathMap(string ID, string Path)
    ContextID = ID;
    HTMLPath = Path;

Writing the Results

Since we'd like our changes to be written immediately to the configuration file, we implement this as a write-through cache. The SaveMappingFile() method called from ShowHelpMappingDialog() takes care of this:

//  Saves the specified StringDictionary that contains ID to Path mappings to the
//  XML mapping file.
private static void SaveMappingFile(StringDictionary sdMappings)
  // Create a new XML document and initialize it with the XML declaration and the
  // outer IDMap element.
  XmlDocument docMapping = new XmlDocument();
  XmlDeclaration xmlDecl = docMapping.CreateXmlDeclaration("1.0", null, null);
  docMapping.InsertBefore(xmlDecl, docMapping.DocumentElement);   
  XmlElement elIDMap = AddChildElementToNode(docMapping, docMapping,
  // Add the defined mappings between contextID and filename.
  foreach (DictionaryEntry de in sdMappings)   
    XmlElement elMapping = AddChildElementToNode(elIDMap, docMapping,
    elMapping.SetAttribute(mc_sID_ATTRIBUTE_NAME, de.Key as string);
    elMapping.SetAttribute(mc_sHTMLPATH_ATTRIBUTE_NAME, de.Value as string);
    MessageBox.Show(string.Format("Could not write help mapping file '{0}'",
      MappingFilePath), "Context Help Made Easy", MessageBoxButtons.OK,

The AddChildElementToNode() utility function makes the code a bit more readable:

// Small utility method to add XML elements to a parent node.
private static XmlElement AddChildElementToNode(XmlNode node, 
               XmlDocument doc, string elementName)
  XmlElement el = doc.CreateElement(elementName);
  return el;

The Mapping Dialog

The mapping dialog consists of a ListView control, and buttons for editing the topic file name, OK, and Cancel. It is an editor of the list of ContextIDHTMLPathMap structures that contain the current control's contexts. The dialog populates the ListView control, permits editing of the HTML File names in it, and writes the results back to the List<ContextIDHTMLPathMap>.

The entry point for the dialog is the static method ShowHelpWriterHelper() that instantiates the form and initializes its data.

// Static entry point to pop up this form.
public static bool 
       ShowHelpWriterHelper(List<ContextIDHTMLPathMap> contextIDs)
  FHelpMappingDialog frmHelper = new FHelpMappingDialog();
  frmHelper.IDList = contextIDs;  // Populate the treelist.
  if( frmHelper.lvMapping.Items.Count > 0 )
  frmHelper.ShowDialog();         // Popup the form.
  if (frmHelper.Changed)
    // For each item in the ListView,
    // change the path map to correspond to the UI.
    foreach (ListViewItem lvi in frmHelper.lvMapping.Items)
      ContextIDHTMLPathMap pathMap = (ContextIDHTMLPathMap)lvi.Tag;
      pathMap.HTMLPath = (string)lvi.SubItems[0].Text.Trim();
  return frmHelper.Changed;

The ListView is populated in the IDList property set method:

// Gets and sets the list of ids.  The setter updates the UI.
public List<ContextIDHTMLPathMap> IDList
    foreach (ContextIDHTMLPathMap pathMap in value)

// Utility to add a node to the treelist.
private void AddMappingNode(ContextIDHTMLPathMap pathMap)
  ListViewItem lvi = new ListViewItem(pathMap.HTMLPath);
  lvi.Tag = pathMap;

Other methods in the dialog are what you'd probably expect:

// Begin editing the label of the selected
// item when they click this button
private void btnEditTopicFile_Click(object sender, EventArgs e)
  if( lvMapping.SelectedItems.Count == 1 )
    ListViewItem lvi = lvMapping.SelectedItems[0];

// If the item has changed after editing
// the label, flag the dialog as changed.
private void lvMapping_AfterLabelEdit(object sender, 
             LabelEditEventArgs e)
  this.Changed = true;

The details of implementing the dialog can be found in the source attached to this article, but this should give you the basic idea.

Finishing Touches

We now have a functioning help system that can easily be configured post-compilation by a help author. This section describes a few additional features to give you a sense of how you can extend the system.

Handling the "?" Dialog Help Button

When you have a dialog with an associated ContextID (e.g., one derived from

), you may want the user to be able to click on the "?" help button to bring up the HTML help for that context. We'll modify FormEx so that all dialogs have this behavior. Set the following properties in the FormEx designer to get the help button to appear:

HelpButton = true;
MaximizeBox = false;
MinimizeBox = false;

Now we need to override the OnHelpButtonClicked() method to call our help handler and cancel the default behavior of changing the cursor.

protected override void OnHelpButtonClicked(CancelEventArgs e)
  e.Cancel = true;

We're done :).

Handling Tab Controls

With a tab (or similar) control, you may want to change the default behavior of the help system. For example, you'll probably want the ContextID returned when a tab is focused to be the ContextID of the control contained on the TabPage. To do this, we just override the ContextID property of the form that contains the tab control.

public override string ContextHelpID
    switch (this.tcSettings.SelectedIndex)
      case 0: return settingsGeneral1.ContextHelpID;
      case 1: return settingsConfiguration1.ContextHelpID;
    return base.ContextHelpID;

The Source Code and Sample Application

The attached sample application contains the source code for a fully instrumented application illustrating the principles from this article. It also contains a help file "ContextHelpMadeEasy.chm" that you can use to test the application. This file should be located in the same directory as the built executable. The topic file names in ContextHelpMadeEasy.chm are:

  • Configuration_Settings.htm
  • Configuration_Settings.htm
  • Context_Help_Made_Easy_Test_Application.htm
  • General_Settings.htm
  • Settings.htm
  • Topic_A.htm
  • Topic_B.htm
  • Topic_C.htm
  • Topic_D.htm
  • UI_1.htm
  • UI_2.htm
  • UI_1_Left_Side.htm
  • UI_1_Right_Side.htm
  • UI_2.htm

To see how it works, run the sample application and navigate to any of the application screens using the File and View menus. Place your cursor in some control and then, while holding down the Control key, click F1. The help author's dialog will appear, which you can use to associate any of these topics with the current context.


I'd like to thank my employer, Serena Software, for encouraging me to share these ideas with the .NET community. And without my co-workers, of course, I'd be utterly lost.

Version History

  • February 2, 2007: Initial version.
  • February 8, 2007: Textual edits, TOC and reference to Charles Williams' IExtenderProvider suggestion.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Tom Clement
Product Manager
United States United States
I've been programming in C, C++, Visual Basic and C# for over 30 years. I've worked at Sierra Systems, ViewStar, Mosaix, Lucent, Avaya, Avinon, Apptero, Serena and now Guidewire Software in various roles over my career.

You may also be interested in...


Comments and Discussions

QuestionNo associated topic when the F1 key is pressed Pin
Sam Hobbs24-Jan-16 8:45
memberSam Hobbs24-Jan-16 8:45 
QuestionWPF Sample Pin
mahsarakhsha25-Jun-12 22:24
membermahsarakhsha25-Jun-12 22:24 
AnswerRe: WPF Sample Pin
Tom Clement26-Jun-12 1:48
mentorTom Clement26-Jun-12 1:48 
GeneralMy vote of 5 Pin
jujiro28-Mar-11 9:12
memberjujiro28-Mar-11 9:12 
GeneralRe: My vote of 5 Pin
Tom Clement6-Jun-11 22:33
memberTom Clement6-Jun-11 22:33 
QuestionModal behaviour using method ShowHelp Pin
marselo3-Dec-10 0:37
membermarselo3-Dec-10 0:37 
GeneralVery good. Pin
The Manoj Kumar21-Oct-10 14:19
memberThe Manoj Kumar21-Oct-10 14:19 
GeneralRe: Very good. Pin
Tom Clement6-Jun-11 22:31
memberTom Clement6-Jun-11 22:31 
GeneralNew improvements on the improvements Pin
Geert van Horrik29-Dec-08 22:53
memberGeert van Horrik29-Dec-08 22:53 
GeneralRe: New improvements on the improvements Pin
Tom Clement30-Dec-08 9:28
memberTom Clement30-Dec-08 9:28 
GeneralRe: New improvements on the improvements Pin
manchanx19-Mar-15 14:31
professionalmanchanx19-Mar-15 14:31 
GeneralRe: New improvements on the improvements Pin
Geert van Horrik20-Mar-15 0:50
memberGeert van Horrik20-Mar-15 0:50 
GeneralRe: New improvements on the improvements Pin
manchanx20-Mar-15 0:53
professionalmanchanx20-Mar-15 0:53 
NewsMessage Closed Pin
23-Sep-07 21:16
memberkanzz23-Sep-07 21:16 
GeneralSome great improvements to this article [modified] Pin
Tom Clement23-Jul-07 13:47
memberTom Clement23-Jul-07 13:47 
GeneralRe: Some great improvements to this article Pin
wzychla24-Jul-07 2:48
memberwzychla24-Jul-07 2:48 
GeneralRe: Some great improvements to this article Pin
xqc3217-Nov-07 4:22
memberxqc3217-Nov-07 4:22 


GeneralMessage Closed Pin
7-Nov-07 4:26
memberxqc3217-Nov-07 4:26 
GeneralMessage Closed Pin
7-Nov-07 4:21
memberxqc3217-Nov-07 4:21 
QuestionLocating the ExtenderProvider on the form Pin
mtruism4-Jun-07 21:15
membermtruism4-Jun-07 21:15 
AnswerRe: Locating the ExtenderProvider on the form Pin
sprucely15-Jun-07 13:48
membersprucely15-Jun-07 13:48 
GeneralProblems with .CHM file in XP Pin
andre1234529-May-07 2:31
memberandre1234529-May-07 2:31 
GeneralRe: Problems with .CHM file in XP Pin
Giorgi Dalakishvili29-May-07 3:00
memberGiorgi Dalakishvili29-May-07 3:00 
GeneralRe: Problems with .CHM file in XP Pin
andre1234529-May-07 5:01
memberandre1234529-May-07 5:01 
GeneralRe: Problems with .CHM file in XP Pin
socalshyguy14-Jun-07 20:30
membersocalshyguy14-Jun-07 20:30 
QuestionRe: Problems with .CHM file in XP Pin
beruschka11-Jul-07 6:21
memberberuschka11-Jul-07 6:21 
AnswerRe: Problems with .CHM file in XP Pin
beruschka12-Jul-07 0:35
memberberuschka12-Jul-07 0:35 
Generalvery good Pin
Dunbar.Cui13-May-07 18:12
memberDunbar.Cui13-May-07 18:12 
GeneralRe: very good Pin
Tom Clement14-May-07 8:29
memberTom Clement14-May-07 8:29 
QuestionNaive Question: How is this better than the built in HelpProvider? Pin
flipdoubt28-Apr-07 4:24
memberflipdoubt28-Apr-07 4:24 
QuestionRe: Naive Question: How is this better than the built in HelpProvider? Pin
flipdoubt3-May-07 2:48
memberflipdoubt3-May-07 2:48 
AnswerRe: Naive Question: How is this better than the built in HelpProvider? Pin
Tom Clement3-May-07 14:24
memberTom Clement3-May-07 14:24 
GeneralRe: Naive Question: How is this better than the built in HelpProvider? Pin
flipdoubt4-May-07 4:14
memberflipdoubt4-May-07 4:14 
GeneralRe: Naive Question: How is this better than the built in HelpProvider? Pin
Tom Clement4-May-07 8:09
memberTom Clement4-May-07 8:09 
GeneralAwesome But Pin
Sacha Barber23-Mar-07 7:22
memberSacha Barber23-Mar-07 7:22 
GeneralRe: Awesome But Pin
Tom Clement23-Mar-07 10:25
memberTom Clement23-Mar-07 10:25 
GeneralRe: Awesome But Pin
Sacha Barber24-Mar-07 0:10
memberSacha Barber24-Mar-07 0:10 
GeneralRe: Awesome But Pin
Tom Clement2-Apr-07 8:38
memberTom Clement2-Apr-07 8:38 
GeneralControl Pin
Sk8tz20-Feb-07 21:55
memberSk8tz20-Feb-07 21:55 
GeneralRe: Control Pin
Tom Clement21-Feb-07 6:55
memberTom Clement21-Feb-07 6:55 
GeneralInforming, lucid, and very useful. Pin
Written Works7-Feb-07 23:56
memberWritten Works7-Feb-07 23:56 
GeneralRe: Informing, lucid, and very useful. Pin
Tom Clement8-Feb-07 5:15
memberTom Clement8-Feb-07 5:15 
GeneralRe: Informing, lucid, and very useful. Pin
Sebrell9-Feb-07 0:26
memberSebrell9-Feb-07 0:26 
AnswerRe: Informing, lucid, and very useful. Pin
Tom Clement9-Feb-07 10:05
memberTom Clement9-Feb-07 10:05 
GeneralXml file reading in c# Pin
kishore yakkali6-Feb-07 0:52
memberkishore yakkali6-Feb-07 0:52 
GeneralRe: Xml file reading in c# [modified] Pin
Tom Clement6-Feb-07 7:12
memberTom Clement6-Feb-07 7:12 
QuestionReading xml File in c# Pin
kishore yakkali6-Feb-07 0:47
memberkishore yakkali6-Feb-07 0:47 
NewsWiki Pin
Tom Clement5-Feb-07 7:50
memberTom Clement5-Feb-07 7:50 
GeneralSuperb Stuff Pin
seankearon4-Feb-07 23:18
memberseankearon4-Feb-07 23:18 
GeneralRe: Superb Stuff [modified] Pin
Tom Clement5-Feb-07 7:49
memberTom Clement5-Feb-07 7:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.171207.1 | Last Updated 2 Feb 2007
Article Copyright 2007 by Tom Clement
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid