WPF Richtextbox Application.Find Text 跨越多次运行 [英] WPF Richtextbox Application.Find Text spanning Multiple runs

查看:24
本文介绍了WPF Richtextbox Application.Find Text 跨越多次运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为 WPF 富文本框实现 Application.Find 命令.假设我正在寻找专家".听起来很容易.但是由于 wpf 的性质,如果expert"中的所有其他字母都加粗,则 Richtextbox 包含 e*x*p*e*r*t* 这意味着存在六次运行.我有一个起始文本指针.我想弄清楚的是如何获得结尾的 textPointer 以便我可以创建一个 TextRange,我可以用它来创建选择.

I'm trying to implement the Application.Find command for the WPF richtextbox. Let's say I'm searching for "expert". Sounds easy enough. But due to the nature of wpf, if every other letter in "expert" is bolded, then the richtextbox contains e*x*p*e*r*t* and that means six runs exist. I have a starting textPointer. What I'm trying to figure out is how to get the ending textPointer so that I can create a TextRange that I can use to create the Selection.

在这个例子中,起始文本指针在第一次运行中,结束文本指针应该在最后一次运行中.如果您知道运行和运行中的偏移量,是否有一种简单的方法来生成文本指针?我尝试使用第一个文本指针的偏移量生成它,但没有奏效,因为偏移量不在第一次运行之内.

In this example, the starting textpointer is in the first run, and the ending textpointer should be in the last run. Is there a simple way to generate a textpointer if you know the run and the offset within the run? I tried generating it using a offset from the first textpointer but that did not work because the offset was not within the first run.

作为 WPF Richtextbox 的相对新手,这个让我很难过.我想这个问题已经被处理和解决了.我确实找到了一个部分解决方案,但它只适用于单次运行,并没有解决多次运行的情况.

As a relative newbie to the WPF richtextbox, this one has me stumped. I imagine that this problem has already been tackled and solved. I did find one partial solution but it only worked on a single run and does not address the multiple run situation.

推荐答案

思路是找到第一个字符的偏移量(IndexOf),然后在这个索引处找到 TextPointer(但是通过只计算文本字符).

The idea is to find the offset of the first character (IndexOf) and then to find the TextPointer at this index (but by counting only text characters).

public TextRange FindTextInRange(TextRange searchRange, string searchText)
{
    int offset = searchRange.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase);
    if (offset < 0)
        return null;  // Not found

    var start = GetTextPositionAtOffset(searchRange.Start, offset);
    TextRange result = new TextRange(start, GetTextPositionAtOffset(start, searchText.Length));

    return result;
}

TextPointer GetTextPositionAtOffset(TextPointer position, int characterCount)
{
    while (position != null)
    {
        if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
        {
            int count = position.GetTextRunLength(LogicalDirection.Forward);
            if (characterCount <= count)
            {
                return position.GetPositionAtOffset(characterCount);
            }

            characterCount -= count;
        }

        TextPointer nextContextPosition = position.GetNextContextPosition(LogicalDirection.Forward);
        if (nextContextPosition == null)
            return position;

        position = nextContextPosition;
    }

    return position;
}

这是如何使用代码:

TextRange searchRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
TextRange foundRange = FindTextInRange(searchRange, "expert");
foundRange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Red));

这篇关于WPF Richtextbox Application.Find Text 跨越多次运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆