在 C# 中超链接到一行 RichTextBox

Hyperlink to a line of RichTextBox in C#

我正在寻找一种在 RichTextBox 中创建指向同一个 RichTextBox 的一行文本的超链接的方法。

我刚刚找到了如何使用 Internet 链接来做到这一点,但我没有找到一种方法来使用控件内的相同文本来做到这一点(就像 MS Word 中的超链接指向 header 或书签)。

提前致谢。 - 建设银行

不,除非您自己编写必要的代码,否则这是行不通的。

两条建议:

  • 使用 link 始终以 www.
  • 开头的简单解决方法
  • 带有任意 link 文本的更好的解决方案

让我们看看这两个选项..:[=​​16=]

  • 使用识别 URL 的内置功能似乎是正确的开始方式,但 link 总是必须 看起来 像URL,不像 hyperlink 到锚。 : #234# 这真的很简单..

一个工作示例可以像这样简单:

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(); };
}
  • 选项二:如果您希望对 link 的阅读方式有更多选择,您可以这样做:

首先将每个格式格式化为

  • 以特殊字符开头,说波浪号“~”
  • 如果需要,将其格式化为蓝色和下划线
  • 要么把它变成一个词,要么用下划线替换 space 并格式化它们,使前景色等于背景色

现在可以完成这项工作了:

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);
}

这是两个并排的版本,一次在顶部,然后在单击 link:

两个版本都可以正常工作,尽管都可以进行更多检查。

请注意,我懒得在第二个示例中格式化伪 link,因此它们显示了波浪号和哈希值..

不难写一个可以插入格式的辅助函数;搜索仍然会在文本中搜索,而不是在 Rtf 属性..

中搜索