简体   繁体   中英

Hyperlink to a line of RichTextBox in C#

I am looking a way to create a HyperLink in a RichTextBox pointing to a line of the text of the same RichTextBox.

I just found how to do that with Internet Links but I don't find a way to do it with the same text inside of the control (It's like Hyperlinks in MS Word pointing to a header or bookmark).

Thanks in Advance. - CCB

No, this will not work unless you code the necessary stuff yourself.

Two suggestions:

  • A simple workaround with links always starting with www.
  • The nicer solution with arbitrary link text

Let's have a look at both options..:

  • Using the built-in functionality of recognizing an URL seems the right way to start, but the link will always have to look like a URL, not like a hyperlink to an anchor.. If you can live with a solution that has, say, links like this: www.goto.234 and anchors like this: #234# this is really rather simple..

A working example can be as simple as this:

private void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e)
{
    var s = e.LinkText.Split('.');
    string anchor = s[2];

    int a = richTextBox1.Text.IndexOf("#" + anchor + "#" );
    if (a >= 0) richTextBox1.SelectionStart = a; else return;  // do add more checks!
    richTextBox1.SelectionLength = 0;
    Text = anchor + " @ " + a;
    //richTextBox1.ScrollToCaret();    <<--- this crashes on my machine!
    // so I take the jump out of the click event and it works: 
    Timer ttt = new Timer() { Interval = 100 };
    ttt.Tick += (ss, ee) => { richTextBox1.ScrollToCaret(); ttt.Stop(); };
}
  • Option two: If you'd rather have more choice of how the links should read you can do this:

Start by formatting each to

  • Start with a special character, say a tilde '~'
  • format it to look blue and underlined if you want to
  • Either make it one word or replace space by underlines and format those to have the forecolor equal to the backcolor

Now this can do the job:

public string delimiters = " ()[]{}!&?=/\\,;.\r\n";

private void richTextBox2_Click(object sender, EventArgs e)
{
    int sstart = -1;
    string s = getWordAt(richTextBox2.Text, 
                         richTextBox2.SelectionStart, delimiters, out sstart);
    if (s.Length < 3) return;
    string char1 = s.Substring(0, 1);
    if (char1 == "~")
    {
        int p = richTextBox2.Text.IndexOf("#" + s.Substring(1));
        if (p >= 0) { richTextBox2.SelectionStart = p; richTextBox2.ScrollToCaret(); }
    }
}

public static string getWordAt(string text, int cursorPos, 
                               string delimiters, out int selStart)
{
    int startPos = 0;
    selStart = startPos;
    if ((cursorPos < 0) | (cursorPos > text.Length) | (text.Length == 0)) return "";
    if ((text.Length > cursorPos) & (delimiters.Contains(text[cursorPos]))) return "";
    int endPos = text.Length - 1;
    if (cursorPos == text.Length) endPos = text.Length - 1;
    else { for (int i = cursorPos; i < text.Length; i++) 
     { if (delimiters.Contains(text[i])) { endPos = i - 1; break; } } }
    if (cursorPos == 0) startPos = 0;
    else { for (int i = cursorPos; i > 0; i--) 
    { if (delimiters.Contains(text[i])) { startPos = i + 1; break; } } }
    selStart = startPos;

    return text.Substring(startPos, endPos - startPos + 1);
}

Here are the two versions side by side, once at the top then after clicking on a link:

在此处输入图片说明 在此处输入图片说明

Both versions work fine, although both could do with some more checks.

Note that I was too lazy to format the pseudo-links in the second example, so they show their tildes and hashes..

Not hard to write a helper function that can insert the formatting; the search will still work as it searches in the Text, not the Rtf property..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM