以编程方式在WPF RichTextBox(FlowDocument)中选择文本范围

我有这个WPF RichTextBox,我想以编程方式选择给定范围的字母/单词并突出显示它。 我试过这个,但它不起作用,可能是因为我没有考虑一些隐藏的FlowDocument标签或类似的东西。 例如,我想选择字母3-8但选择2-6):

var start = MyRichTextBox.Document.ContentStart;
var startPos = start.GetPositionAtOffset(3);
var endPos = start.GetPositionAtOffset(8);
var textRange = new TextRange(startPos,endPos);
textRange.ApplyPropertyValue(TextElement.ForegroundProperty,
    new SolidColorBrush(Colors.Blue));
textRange.ApplyPropertyValue(TextElement.FontWeightProperty, 
    FontWeights.Bold);

我意识到RichTextBox的处理比我想象的要复杂一些:)

更新:我在MSDN论坛上得到了几个答案:这个线程的“dekurver”seid:

您指定的偏移量不是字符偏移量,而是符号偏移量。 你需要做的是获得一个你认为与文本相邻的TextPointer,然后你可以添加字符偏移量。

而“LesterLobo”则表示:

您需要遍历段落和内联来查找Next,然后在循环中找到它们的偏移量以应用特定文本的所有外观。 请注意,当你编辑你的文本会移动,但你的亮点不会移动,因为它与偏移量不关联的文本。 然而,您可以创建自定义运行并为其提供亮点...

如果有人知道他们绕过FlowDocuments的方式,仍然会喜欢看到一些示例代码...

编辑我有一个版本的Kratz VB代码工作,它看起来像这样:

private static TextPointer GetPoint(TextPointer start, int x)
{
    var ret = start;
    var i = 0;
    while (i < x && ret != null)
    {
        if (ret.GetPointerContext(LogicalDirection.Backward) == 
TextPointerContext.Text ||
            ret.GetPointerContext(LogicalDirection.Backward) == 
TextPointerContext.None)
            i++;
        if (ret.GetPositionAtOffset(1, 
LogicalDirection.Forward) == null)
            return ret;
        ret = ret.GetPositionAtOffset(1, 
LogicalDirection.Forward);
    }
    return ret;
}

我使用它是这样的:

Colorize(item.Offset, item.Text.Length, Colors.Blue);

private void Colorize(int offset, int length, Color color)
{
    var textRange = MyRichTextBox.Selection;
    var start = MyRichTextBox.Document.ContentStart;
    var startPos = GetPoint(start, offset);
    var endPos = GetPoint(start, offset + length);

    textRange.Select(startPos, endPos);
    textRange.ApplyPropertyValue(TextElement.ForegroundProperty, 
new SolidColorBrush(color));
    textRange.ApplyPropertyValue(TextElement.FontWeightProperty, 
FontWeights.Bold);
}

Public Function GoToPoint(ByVal start As TextPointer, ByVal x As Integer) As TextPointer
    Dim out As TextPointer = start
    Dim i As Integer = 0
    Do While i < x
        If out.GetPointerContext(LogicalDirection.Backward) = TextPointerContext.Text Or _
             out.GetPointerContext(LogicalDirection.Backward) = TextPointerContext.None Then
            i += 1
        End If
        If out.GetPositionAtOffset(1, LogicalDirection.Forward) Is Nothing Then
            Return out
        Else
            out = out.GetPositionAtOffset(1, LogicalDirection.Forward)
        End If


    Loop
    Return out
End Function

试试这个,这应该返回给定字符偏移量的文本指针。 (对不起,在VB中,但多数民众赞成在我的工作...)


尝试一下:

var textRange = MyRichTextBox.Selection;
var start = MyRichTextBox.Document.ContentStart;
var startPos = start.GetPositionAtOffset(3);
var endPos = start.GetPositionAtOffset(8);
textRange.Select(startPos, endPos);
textRange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Blue));
textRange.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);

我尝试使用KratzVB发布的解决方案,但发现它忽略了换行符。 如果你想计算 r和 n符号,那么这个代码应该工作:

private static TextPointer GetPoint(TextPointer start, int x)
{

        var ret = start;
        var i = 0;
        while (ret != null)
        {
            string stringSoFar = new TextRange(ret, ret.GetPositionAtOffset(i, LogicalDirection.Forward)).Text;
            if (stringSoFar.Length == x)
                    break;
            i++;
            if (ret.GetPositionAtOffset(i, LogicalDirection.Forward) == null)
                return ret.GetPositionAtOffset(i-1, LogicalDirection.Forward)

        }
        ret=ret.GetPositionAtOffset(i, LogicalDirection.Forward);
        return ret;
}
链接地址: http://www.djcxy.com/p/61119.html

上一篇: Select Range of Text in WPF RichTextBox (FlowDocument) Programmatically

下一篇: How to show a flowdocument in multiple pages like Word?