1

尝试在 WPF Richtextbox 中选择特定单词并为其着色,但我的方法仅选择该单词的前 5 个字母。索引 0,1 和 2 似乎是空字符串,尽管我的 rtb 中的第一个单词是“private”并且之前没有空字符串。

这个问题的原因可能是什么?

public  void FormatRtbText(RichTextBox rtb)
    {
        int x, y;
        string str = "private";

        var text = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd).Text;

        x = text.IndexOf(str);
        y = x + str.Length;

        var range = new TextRange(rtb.Document.ContentStart.GetPositionAtOffset(x), rtb.Document.ContentStart.GetPositionAtOffset(y));
        range.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);

    }
4

2 回答 2

1

GetPositionAtOffset在计算偏移量时将 3 个事物视为符号:

TextElement 元素的开始或结束标记。

包含在 InlineUIContainer 或 BlockUIContainer 中的 UIElement 元素。请注意,这样的 UIElement 始终只计为一个符号;UIElement 包含的任何其他内容或元素均不计为符号。

文本 Run 元素内的 16 位 Unicode 字符。

这里前两个符号是ParagraphRun元素。因此,你TextRange是你想要的背后的两个符号。这段代码应该可以工作。(这段代码所做的只是跳过符号,直到下一个符号是文本。)

TextPointer start = rtb.Document.ContentStart;
while (start.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
{
    start = start.GetNextContextPosition(LogicalDirection.Forward);
    if (start == null) return;
}
...
var range = new TextRange(start, start.GetPositionAtOffset(y));
于 2015-05-20T19:28:26.187 回答
0

我发现 wpf rtf 框返回的偏移量实际上毫无价值。他们没有考虑到文本框需要的隐藏字符。框中的每个新段落、图像等都会添加更多的隐藏字符,这些字符会扭曲偏移量。

这是我想出的搜索接近插入符号位置的匹配项。

  private TextRange FindText(string findText)
    {
      var fullText = DoGetAllText();
      if (string.IsNullOrEmpty(findText) || string.IsNullOrEmpty(fullText) || findText.Length > fullText.Length)
        return null;

      var textbox = GetTextbox();
      var leftPos = textbox.CaretPosition;
      var rightPos = textbox.CaretPosition;

      while (true)
      {
        var previous = leftPos.GetNextInsertionPosition(LogicalDirection.Backward);
        var next = rightPos.GetNextInsertionPosition(LogicalDirection.Forward);
        if (previous == null && next == null)
          return null; //can no longer move outward in either direction and text wasn't found

        if (previous != null)
          leftPos = previous;
        if (next != null)
          rightPos = next;

        var range = new TextRange(leftPos, rightPos);
        var offset = range.Text.IndexOf(findText, StringComparison.InvariantCultureIgnoreCase);
        if (offset < 0)
          continue; //text not found, continue to move outward

        //rtf has broken text indexes that often come up too low due to not considering hidden chars.  Increment up until we find the real position
        var findTextLower = findText.ToLower();
        var endOfDoc = textbox.Document.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
        for (var start = range.Start.GetPositionAtOffset(offset); start != endOfDoc; start = start.GetPositionAtOffset(1))
        {
          var result = new TextRange(start, start.GetPositionAtOffset(findText.Length));
          if (result.Text?.ToLower() == findTextLower)
          {
            return result;
          }
        }
      }
    }

如果您想突出显示匹配项,那么只需将此方法更改为 void 并在找到匹配项时执行此操作:

textbox.Selection.Select(result.Start, result.End);
于 2017-10-28T06:21:18.197 回答