【问题标题】:Custom links in RichTextBoxRichTextBox 中的自定义链接
【发布时间】:2010-04-02 15:54:09
【问题描述】:

假设我希望每个以# 开头的单词都在双击时生成一个事件。为此,我实现了以下测试代码:

private bool IsChannel(Point position, out int start, out int end)
{
    if (richTextBox1.Text.Length == 0)
    {
        start = end = -1;
        return false;
    }

    int index = richTextBox1.GetCharIndexFromPosition(position);
    int stop = index;

    while (index >= 0 && richTextBox1.Text[index] != '#')
    {
        if (richTextBox1.Text[index] == ' ')
        {
            break;
        }
        --index;
    }

    if (index < 0 || richTextBox1.Text[index] != '#')
    {
        start = end = -1;
        return false;
    }

    while (stop < richTextBox1.Text.Length && richTextBox1.Text[stop] != ' ')
    {
        ++stop;
    }
    --stop;

    start = index;
    end = stop;

    return true;
}

private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
    textBox1.Text = richTextBox1.GetCharIndexFromPosition(new Point(e.X, e.Y)).ToString();
    int d1, d2;
    if (IsChannel(new Point(e.X, e.Y), out d1, out d2) == true)
    {
        if (richTextBox1.Cursor != Cursors.Hand)
        {
            richTextBox1.Cursor = Cursors.Hand;
        }
    }
    else
    {
        richTextBox1.Cursor = Cursors.Arrow;
    }
}

这处理检测以# 开头的单词,并在鼠标悬停在它们上方时使鼠标光标变成一只手。但是,我有以下两个问题:

  1. 如果我尝试为richTextBox1 实现双击事件,我可以检测到单击某个单词的时间,但是该单词会突出显示(选中),我想避免这种情况。我可以通过选择文本的结尾以编程方式取消选择它,但这会导致闪烁,我想避免这种情况。有什么方法可以做到这一点?
  2. GetCharIndexFromPosition 方法返回离光标最近的字符的索引。这意味着,如果我的 RichTextBox 包含的唯一内容是以 # 开头的单词,那么无论富文本控件位于何处,光标都将是一只手。当它悬停在我感兴趣的单词的一部分的实际单词或字符上时,我怎样才能使它成为一只手?实现的 URL 检测也部分地受到这个问题的影响。如果我启用 URL 检测并且只在富文本编辑器中写入 www.test.com,那么只要光标位于链接的或下方,它就会是一只手。但是,如果它位于链接的右侧,它将不是一只手。如果使光标成为手,当且仅当它在文本上被证明太难时,即使使用此功能我也很好。

我猜我将不得不求助于某种 Windows API 调用,但我真的不知道从哪里开始。

我正在使用 Visual Studio 2008,我想自己实现它。

更新: 如果我能做到,只有通过拖动鼠标光标并以编程方式才能通过双击来选择任何文本,那么闪烁问题将得到解决。这更容易实现吗?因为在这种情况下,我真的不在乎是否可以通过双击来选择文本。

【问题讨论】:

  • 虽然这是一篇相当老的文章:您可能会从中获得一些关于在 RichTextBox 中创建自定义链接的想法:codeproject.com/KB/edit/RichTextBoxLinks.aspx。双击 RichTextBox 中的 URL 也会选择 URL 的一部分。一个“离谱的想法”:如果你“过滤”双击#字符,确保#字符是空格分隔的?这样,双击它只会选择 # 字符,但随后在 DoubleClick 事件处理程序中,您可以将选择范围扩展为“抓取”# 符号后所需的内容。
  • 没错,双击一个 URL 也会选择它的一部分。我想避免这种情况,我希望我的链接无法通过双击来选择,但可以通过拖动鼠标光标来选择(是否可以通过双击来选择没有文本?这也适用于我)。我不能确保 # 字符是空格分隔的,它可能不是。谢谢你的文章,我会看看他们有什么。看起来很复杂,但不完全是我需要的:)。

标签: c# .net winforms user-controls


【解决方案1】:

关于第 (2) 点,您可以尝试:

if (richTextBox1.Text.Length == 0){ ... } 之后

//get the mouse point in client coordinates Point clientPoint = richTextBox1.PointToClient(richTextBox1.PointToScreen(position)); int index = richTextBox1.GetCharIndexFromPosition(position); //get the position of the closest char Point charPoint = richTextBox1.GetPositionFromCharIndex(index); bool notOnTheSameLine = ((clientPoint.Y < charPoint.Y) || (clientPoint.Y > charPoint.Y + richTextBox1.Font.Height)); bool passedTheWord = (clientPoint.X > charPoint.X + richTextBox1.Font.SizeInPoints); if (notOnTheSameLine || passedTheWord) { start = end = -1; return false; }

对于第 (1) 点,跟随链接的方式可能与 dbl-click 不同?也许 cntl-click 可以避免单词被选中的问题......

【讨论】:

  • 谢谢,效果很好。这是我最重要的问题,我想被选中这个词没什么大不了的。如果没有人发布更好的东西,我会再等一下然后接受你的回答:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
相关资源
最近更新 更多