绑定Run.TextProperty后,文本修改后值自动恢复为旧值
解决RichTextBox绑定Run.Text后编辑值被恢复的问题
嘿,这个问题我之前也踩过坑!根源在于直接绑定Run.TextProperty到你的OpenedFile.Body属性在WPF的RichTextBox中是不可靠的。当你编辑内容时,WPF的文档编辑引擎会偷偷对FlowDocument内部的Run元素做手脚——比如拆分、合并甚至重新创建Run实例,这直接导致你一开始设置的绑定关系失效,结果就是你刚输入的内容又被打回旧值。
靠谱的实现方式:用双向转换器绑定整个Document属性
我们可以写一个IValueConverter,搞定字符串和FlowDocument之间的双向转换,然后把RichTextBox的Document属性直接绑定到OpenedFile.Body。这样就能绕开单个Run绑定的坑。
第一步:写字符串和FlowDocument的双向转换器
using System; using System.Windows.Data; using System.Windows.Documents; public class StringToFlowDocumentConverter : IValueConverter { // 把字符串转成FlowDocument给RichTextBox显示 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string textContent = value as string; if (string.IsNullOrWhiteSpace(textContent)) { return new FlowDocument(new Paragraph(new Run(string.Empty))); } var document = new FlowDocument(); var paragraph = new Paragraph(new Run(textContent)); document.Blocks.Add(paragraph); return document; } // 把RichTextBox的FlowDocument转回字符串更新源属性 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { var flowDocument = value as FlowDocument; if (flowDocument == null) { return string.Empty; } var textRange = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd); // 移除TextRange自带的末尾段落标记,按需调整 return textRange.Text.TrimEnd('\r', '\n'); } }
第二步:修改绑定逻辑,用转换器绑定Document
// 实例化转换器 var textConverter = new StringToFlowDocumentConverter(); // 创建绑定,关联到OpenedFile的Body属性 Binding documentBinding = new Binding("Body") { Source = OpenedFiles[index], Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, Converter = textConverter }; // 创建RichTextBox并设置绑定 RichTextBox richTextBox = new RichTextBox(); richTextBox.SetBinding(RichTextBox.DocumentProperty, documentBinding); // 可选:给文档加一点默认样式,比如内边距 if (richTextBox.Document is FlowDocument doc) { doc.PagePadding = new System.Windows.Thickness(8); }
为什么这个方案能解决问题?
- 我们不再依赖单个
Run的绑定,而是直接绑定RichTextBox的整个Document属性,WPF编辑引擎对内部元素的调整不会影响顶层的绑定关系。 - 双向转换器保证了
OpenedFile.Body和RichTextBox内容的双向同步:源属性更新时自动转成文档显示,用户编辑内容时自动转回字符串更新源。
额外提示
- 如果你的需求是支持富文本(比如字体、颜色、段落格式),那上面的纯文本转换器就不够用了——你需要改成用
XamlReader和XamlWriter来序列化/反序列化FlowDocument。但如果只是纯文本内容,这个转换器完全够用。 - 你的
OpenedFile类的INotifyPropertyChanged实现是正确的,这部分不用改,它是绑定能正常工作的基础。
内容的提问来源于stack exchange,提问作者Alicja Barankiewicz
相关产品推荐
相关产品推荐

