WPF RichTextBox:自动换行后添加新Block及 换行符的实现方法
WPF RichTextBox 问题解答
1. 在RichTextBox末尾添加新Block是否可行?
可行。RichTextBox.Document属于FlowDocument类型,直接操作其Blocks集合就能添加新的Block(比如Paragraph)。
MaxPageWidth仅用于控制文档布局时的页面宽度,它只会让内容在视觉上自动换行,但不会将超出宽度的内容自动拆分为新的Block——视觉换行属于布局层面的表现,不会改变文档的Block结构。
手动添加新Block的示例代码:
if (rtb.Document != null) { var newParagraph = new Paragraph(new Run("新增的段落内容")); rtb.Document.Blocks.Add(newParagraph); }
2. 如何在自动换行位置添加换行符?
默认通过TextRange.Text获取的文本,只会保留硬换行(即Shift+Enter生成的LineBreak元素,或手动添加的LineBreak),视觉上的自动换行是布局渲染的结果,不属于文档结构,因此不会被转换为换行符。
要获取包含自动换行位置的文本,需要遍历文档的布局信息,通过TextPointer的位置坐标判断是否换行,示例代码如下:
public string GetTextWithWrapping(RichTextBox rtb) { if (rtb.Document == null) return string.Empty; StringBuilder sb = new StringBuilder(); TextPointer currentPointer = rtb.Document.ContentStart; while (currentPointer != null && currentPointer.CompareTo(rtb.Document.ContentEnd) < 0) { // 追加当前位置的文本内容 if (currentPointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text) { sb.Append(currentPointer.GetTextInRun(LogicalDirection.Forward)); } // 处理硬换行(Shift+Enter) else if (currentPointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart) { if (currentPointer.GetAdjacentElement(LogicalDirection.Forward) is LineBreak) { sb.Append(Environment.NewLine); } } TextPointer nextPointer = currentPointer.GetNextContextPosition(LogicalDirection.Forward); if (nextPointer != null) { // 通过坐标判断是否为自动换行(两行Y坐标差值大于阈值) Point currentPos = currentPointer.GetCharacterRect(LogicalDirection.Forward).BottomLeft; Point nextPos = nextPointer.GetCharacterRect(LogicalDirection.Forward).BottomLeft; if (nextPos.Y > currentPos.Y + 1) { sb.Append(Environment.NewLine); } } currentPointer = nextPointer; } return sb.ToString(); }
注意:该方法依赖控件的渲染状态,需确保RichTextBox已完成加载(例如在Loaded事件触发后调用),否则无法正确获取行位置坐标。
内容的提问来源于stack exchange,提问作者Wolfgang Schorge
相关产品推荐
相关产品推荐

