2

Is there any way to place multiple links in the LinkLabel control in Windows Forms?

If I just set it like this

this.linkLabel.Text = "";
foreach (string url in urls)
{
    this.linkLabel.Text += url + Environment.NewLine;
}

it merges it into one link.

Thanks in advance.

FrozenHeart
  • 19,844
  • 33
  • 126
  • 242
  • 1
    possible duplicate of [Link Labels c# - displaying a list of them](http://stackoverflow.com/questions/4712191/link-labels-c-sharp-displaying-a-list-of-them) – MethodMan Mar 20 '15 at 19:42
  • @MethodMan This is not a duplicate of that question. That question has to do with adding multiple `LinkLabel` controls to another control. This has to do with adding multiple links to a single `LinkLabel`, something not addressed anywhere in the linked question. – Anthony Mar 20 '15 at 20:22

1 Answers1

8

Yes, though there isn't a way that I can tell to do it directly from the designer, but it is easy to manage via code:

var linkLabel = new LinkLabel();
linkLabel.Text = "(Link 1) and (Link 2)";
linkLabel.Links.Add(1, 6, "Link data 1");
linkLabel.Links.Add(14, 6, "Link data 2");
linkLabel.LinkClicked += (s, e) => Console.WriteLine(e.Link.LinkData);

Basically, the Links collection on the label can host a bunch of links in the LinkLabel. The LinkClicked event contains a reference to the specific link that was clicked so you can access the link data you associated with the link, among other things.

The designer only exposes a LinkArea property which defaults to include all of the text of the LinkLabel. The first Link you add to the Links collection will automatically change the LinkArea property to reflect the first link in the collection.

Something a little closer to what you're asking would look like this:

var addresses = new List<string> {
    "http://www.example.com/page1",
    "http://www.example.com/page2",
    "http://www.example.com/page3",
};

var stringBuilder = new StringBuilder();
var links = new List<LinkLabel.Link>(); 

foreach (var address  in addresses)
{
    if (stringBuilder.Length > 0) stringBuilder.AppendLine();

    // We cannot add the new LinkLabel.Link to the LinkLabel yet because
    // there is no text in the label yet, so the label will complain about
    // the link location being out of range. So we'll temporarily store
    // the links in a collection and add them later.
    links.Add(new LinkLabel.Link(stringBuilder.Length, address.Length, address));        
    stringBuilder.Append(address);
}

var linkLabel = new LinkLabel();
// We must set the text before we add the links.
linkLabel.Text = stringBuilder.ToString();
foreach (var link in links)
{
    linkLabel.Links.Add(link);
}
linkLabel.AutoSize = true;
linkLabel.LinkClicked += (s, e) => {
    System.Diagnostics.Process.Start((string)e.Link.LinkData);
};

I'm attaching the URL itself as the LinkData to the link's I'm creating in the loop so I can extract it out as a string when the LinkClicked event is fired.

Anthony
  • 9,451
  • 9
  • 45
  • 72
  • Thanks a lot, but your solution doesn't work when addresses contains, for example, the following URLs -- `"http://www.example/1"`, `"http://www.example/1/2"` and `"http://www.example/1/3"`. What is the best way to fix it? – FrozenHeart Mar 20 '15 at 23:53
  • I thought of that right after I posted, but didn't have access to a computer to change my answer. Basically, you need to just build your text yourself using a StringBuilder and track the location of the links as you add them. See the modified code sample. – Anthony Mar 23 '15 at 13:03