获取用户在RichTextBox中选择的超链接

时间:2015-06-01 12:51:51

标签: c# wpf .net-3.5 richtextbox

我在使用RichTextBox中的超链接时遇到了困难。 每当用户选择一个段落时,我都可以使用以下代码找到超链接:

TextPointer insertionPosition = richTextBox.Selection.Start;
Paragraph paragraph = insertionPosition.Paragraph;
Hyperlink hyperlink = null;
foreach (Inline inline in paragraph.Inlines)
{
    if (inline is Hyperlink)
    {
       hyperlink = (Hyperlink)inline;
       break;
    }
}

然而,这不是最佳的。显然,当用户选择超链接文本(而不是paragaraph中的其他文本)时,它应该只选择超链接。

示例

  

这是一篇非常长的文字link

如果用户将光标设置为“长”字样,则已找到超链接。

我已经尝试了什么?

尝试#1:

var parent = richTextBox.CaretPosition.Parent;

但是这里父母拥有一个System.Windows.Document.Run-Object,而不是我的超链接。

尝试#2(来自this link):

TextPointer position1 = richTextBox.Selection.Start;
Inline parent = position1.Parent as Inline;
TextPointer position2 = parent.ElementStart;
Hyperlink hl = position2.Parent as Hyperlink;

这里的position2.Parent是一个span-object,但hl的实例始终是null

另外,我看了一下RichTextBox的结构(附图)并尝试了很多其他的东西,最后在StackOverflow上结束。

RichTextBox Structure

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

您可以使用richtextbox.CaretPosition

调用此方法
/// <summary>
/// Returns the hyperlink that covers the given position.
/// </summary>
public static Hyperlink GetHyperlinkFromPosition(TextPointer pos)
{
    if (pos.Paragraph == null) return null;

    Hyperlink hl = FindObjectFirst<Hyperlink>(pos, pos.Paragraph.ElementEnd, false);

    if (hl != null && hl.ContentStart.CompareTo(pos) < 0 && hl.ContentEnd.CompareTo(pos) > 0)
    {
        return hl;
    }

    return null;
}

public static T FindObjectFirst<T>(TextPointer topPos, TextPointer bottomPos, bool searchBackwards) where T : DependencyObject
{
    if (searchBackwards)
    {
        TextPointer currPos = bottomPos;

        while (currPos != null && currPos.CompareTo(topPos) >= 0)
        {
            DependencyObject depObj = currPos.GetAdjacentElement(LogicalDirection.Backward);

            if (depObj is T)
            {
                return (T)depObj;
            }

            currPos = currPos.GetNextContextPosition(LogicalDirection.Backward);
        }
    }
    else
    {
        TextPointer currPos = topPos;

        while (currPos != null && currPos.CompareTo(bottomPos) <= 0)
        {
            DependencyObject depObj = currPos.GetAdjacentElement(LogicalDirection.Forward);

            if (depObj is T)
            {
                return (T)depObj;
            }

            currPos = currPos.GetNextContextPosition(LogicalDirection.Forward);
        }
    }

    return null;
}