LinkLabel Control and Hierarchies

This short article shows a simple example of how to use the LinkLabel control to display a hierarchy of levels that can be clicked, such as folder names.

The LinkLabel control provides a collection property named 'Links' that can be used to contain all the links shown in the text of the LinkLabel control.

A link is added to the Links collection of the LinkLabel control as follows:

linkLabel1.Links.Add(index, count, text);

The index arg is the starting index of the link text within the full text shown by the LinkLabel control. count is the number of characters to be shown as a link within the whole text of the LinkLabel, and text is the text of the link to be shown within the text of the link label.

For example have a LinkLabel control show the following text: "How are you?", with only the 2 words "How" and "you" clickable as links. The rest of the text is not clickable.

To do so, the following is done:

linkLabel1.Text = "How are you?";

linkLabel1.Links.Add(0, 3, "How");

// "How" starts at 0, and is 3 chars long

linkLabel1.Links.Add(8, 3, "you");

// "you" starts at 8, and is also 3 chars long

To find out which link was clicked within the LinkLabel control at run-time, the LinkClicked event can be handled, indicating the index of the clicked link within the Links collection.

A sample event handler method is shown at the end of this article as an example.

To make this process more dynamic, we can just use a list that mirrors the Links collection of the LinkLabel control. This list would contain the text of all the links to be shown in the LinkLabel text.

A variation would be that our list would contain all the links and an extra string, since we possibly would not want to make the last string in the LinkLabel text a link, or clickable.

The code below is an example of how a dynamic LinkLabel control text with links is implemented:

private System.Collections.ArrayList PathLevelList = new System.Collections.ArrayList(6);
private StringBuilder sb = new StringBuilder(6);
private const string ROOT = @"Root\";
// Somewhere in the code we add strings to our list to later populate the Links collection of the LinkLabel control.

PathLevelList.Add("Level_One");
PathLevelList.Add("Level_Two");
PathLevelList.Add("Level_Three");

// We use the private method defined below to re-display the LinkLabel control's text

linkLabel1.Text = GetLinkPath();

// After calling the above method, the linkLable text would be:
Root\Level_One\Level_Two\Level_Three", with "Level_Three" not highlighted as a link and not clickable.
The back slashes are not clickable either, as can be deduced from the method body shown below.
// Method to figure out the text of the LinkLabel control, and which strings within it are shown as links.

private string GetLinkPath()
{
    
int wordCount = 0;
   
int linkTextCharCount = ROOT.Length;
    linkLabel1.Links.Clear();
    // Clear the string builder of level names


    sb.Remove(0, sb.Length);
    //Always add the root level to the string builder, since the root will always show in the link.

    sb.Append(ROOT);        
    // Obviously, Only add levels to the LinkLabel Links collection if our list of levels is not empty.
    //  If our list is empty, we only have the root, which will be the only string shown in the link label text, and not as a link. 
    //    Root will be shown as a clickable link if at least one more level is shown next to it.

    
if (PathLevelList.Count > 0) 

        linkLabel1.Links.Add(0, ROOT.Length - 1, ROOT);    

    // Loop through our list of levels and add each level from the list to the LinkLabel Links collection, except for the last level in the list.
    //   The last level text is diplayed in the text of the LinkLabel control, but not shown as a link.
    
//   Also add a back slash separator between each level name.
   

    foreach (string level in PathLevelList)

    {

        sb.Append(level);

        sb.Append("\\");

        //Don't make the last level's text a link, since it is the current level. It should not be clickable, only the ones before it are, meaning its parents.

         
if (wordCount == PathLevelList.Count - 1)

             break;

             linkLabel1.Links.Add(linkTextCharCount, level.Length, level);

             // Keep track of the starting index of the next link text. We add 1 to the position to account for the back slash.

             linkTextCharCount += (level.Length + 1);

             wordCount++;

    }

    return sb.ToString();

}
 

private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)

{

    int indx = linkLabel1.Links.IndexOf(e.Link);

    //Based on the index returned, which tells us which level in the Links collection was selected.
    //   we can remove the levels that follow the one selected from our list of levels.
    //   we call our private helper method GetLinkPath(), the right path string will be returned, which we can use.

    //   to set the Text property of our LinkLabel control.
   

    while (PathLevelList.Count > indx)

        PathLevelList.RemoveAt(PathLevelList.Count - 1);

    linkLabel1.Text = GetLinkPath();

}