WPF FlowDocument – 绝对字符位置

我有一个WPF RichTextBox,我正在键入一些文本,然后解析整个文本进行处理。 在这个解析过程中,我有每个单词开头和结尾的绝对字符位置。

我想使用这些字符位置将格式应用于某些单词。 但是,我发现FlowDocument使用TextPointer实例来标记文档中的位置。

我发现我可以通过使用开始和结束指针构造TextRange来创建它。 一旦我有TextRange,我可以轻松地将格式应用于其中的文本。 我一直在使用GetPositionAtOffset为我的角色偏移量获取TextPointer,但怀疑它的偏移量与我的不同,因为所选文本的位置与我的预期略有不同。

我的问题是,如何准确地将绝对字符位置转换为TextPointer?

我没有找到将绝对字符位置转换为TextPosition实例的可靠方法。

我的替代解决方案是修改原始解析以处理单个运行而不是捕获RichTextBox的整个文本。 使用与特定Run实例相关的字符位置对我来说是可靠的。 我认为将我的思维方式更多地转向WPF的思维方式有所帮助。

我采用以下方法在FlowDocument中导航运行(受http://blogs.msdn.com/prajakta/archive/2006/10/12/customize-richtextbox-to-allow-only-plain-text-input的启发。 aspx ):

// Get starting pointer TextPointer navigator = flowDocument.ContentStart; // While we are not at end of document while (navigator.CompareTo(flowDocument.ContentEnd) < 0) { // Get text pointer context TextPointerContext context = navigator.GetPointerContext(LogicalDirection.Backward); // Get parent as run Run run = navigator.Parent as Run; // If start of text element within run if (context == TextPointerContext.ElementStart && run != null) { // Get text of run string runText = run.Text; // ToDo: Parse run text } // Get next text pointer navigator = navigator.GetNextContextPosition(LogicalDirection.Forward); } 

我也有这个问题,最终得到了以下RichTextBox扩展方法。 在我的背景下,它完美无缺!

 ///  /// Gets the text pointer at the given character offset. /// Each line break will count as 2 chars. ///  /// The rich text box. /// The offset. /// The TextPointer at the given character offset public static TextPointer GetTextPointerAtOffset(this RichTextBox richTextBox, int offset) { var navigator = richTextBox.Document.ContentStart; int cnt = 0; while (navigator.CompareTo(richTextBox.Document.ContentEnd) < 0) { switch (navigator.GetPointerContext(LogicalDirection.Forward)) { case TextPointerContext.ElementStart: break; case TextPointerContext.ElementEnd: if (navigator.GetAdjacentElement(LogicalDirection.Forward) is Paragraph) cnt += 2; break; case TextPointerContext.EmbeddedElement: // TODO: Find out what to do here? cnt++; break; case TextPointerContext.Text: int runLength = navigator.GetTextRunLength(LogicalDirection.Forward); if (runLength > 0 && runLength + cnt < offset) { cnt += runLength; navigator = navigator.GetPositionAtOffset(runLength); if (cnt > offset) break; continue; } cnt++; break; } if (cnt > offset) break; navigator = navigator.GetPositionAtOffset(1, LogicalDirection.Forward); } // End while. return navigator; } 

我有类似的问题,我发现RichTextBox中有一个错误,因为它不计算“新行字符 – \ r \ n”,所以当你的行号增加时,你会发现你的偏移位置错误了数字计数,我通过抵消偏移的行号解决了我的问题。