【问题标题】:Hyperlink to a line of RichTextBox in C#超链接到 C# 中的一行 RichTextBox
【发布时间】:2016-05-16 14:32:14
【问题描述】:

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

我刚刚找到了如何使用 Internet 链接执行此操作,但我找不到使用控件内部相同文本的方法(这就像 MS Word 中指向标题或书签的超链接)。

提前致谢。 - 建行

【问题讨论】:

  • 我已经简化了我的答案。

标签: c# visual-studio text hyperlink richtextbox


【解决方案1】:

不,除非您自己编写必要的代码,否则这将不起作用。

两个建议:

  • 链接始终以www. 开头的简单解决方法
  • 具有任意链接文本的更好解决方案

让我们看看这两个选项..:

  • 使用识别 URL 的内置功能似乎是正确的开始方式,但链接总是必须看起来像一个 URL,而不是指向锚点的超链接。如果您可以使用具有如下链接的解决方案:www.goto.234 和这样的锚点:#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(); };
}
  • 选项二:如果您希望对链接的读取方式有更多选择,您可以这样做:

首先将每个格式化为

  • 以特殊字符开头,比如波浪号“~”
  • 如果您愿意,可以将其格式化为蓝色并加下划线
  • 要么将其设为一个单词,要么用下划线替换空格并将其格式化为使前景色等于背景色

现在这可以完成工作了:

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

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

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

请注意,我懒得格式化第二个示例中的伪链接,所以它们显示了它们的波浪线和哈希值..

编写一个可以插入格式的辅助函数并不难;搜索仍然可以在 Text 中搜索,而不是在 Rtf 属性中搜索。

【讨论】:

  • “www.goto.123”指向#123#文本,与“www.goto.12x”相同。并且“www.goto.Top”指向 RichTextBox 开头的#Top# 文本,如果我理解错了你的例子,请告诉我。现在,超链接确实需要具有这种格式(www.....)?
  • 是的,使用 linkclicked 事件的问题。您可以选择任何锚定界符;随意玩它,看看你是否可以让它适合你的情况。您的内容是 statix 还是可编辑的?
  • 哦,好的,锚定界符是你写的那些符号,比如标签和波浪号?或者他们是 www.... 和 .goto ?是的,我的内容将是可编辑的。
  • 确实如此。如果用户要创建链接和锚点,要么选择最简单的方法,要么通过按钮和自动格式化支持。我认为我会选择第二种方法。
  • 哦,好的,谢谢!!我将尝试第二种方法,然后我会告诉你它是如何工作的。
猜你喜欢
  • 2020-07-20
  • 1970-01-01
  • 2013-05-06
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多