我可以给你一个好的解决方案,你可以接受它,但在我这样做之前,我将尝试解释为什么 Document 不是首先是 DependencyProperty。
在RichTextBox 控件的生命周期内,Document 属性通常不会改变。 RichTextBox 用 FlowDocument 初始化。该文档已显示,可以通过多种方式进行编辑和修改,但Document 属性的基础值仍然是FlowDocument 的一个实例。因此,它确实没有理由应该是DependencyProperty,即Bindable。如果您有多个位置引用此 FlowDocument,则只需引用一次。由于它在任何地方都是相同的实例,因此每个人都可以访问更改。
我不认为FlowDocument 支持文档更改通知,虽然我不确定。
话虽如此,这里有一个解决方案。在开始之前,由于RichTextBox 没有实现INotifyPropertyChanged 并且Document 不是DependencyProperty,所以当RichTextBox 的Document 属性发生变化时我们没有通知,因此绑定只能是OneWay。
创建一个将提供FlowDocument 的类。绑定需要DependencyProperty的存在,所以这个类继承自DependencyObject。
class HasDocument : DependencyObject
{
public static readonly DependencyProperty DocumentProperty =
DependencyProperty.Register("Document",
typeof(FlowDocument),
typeof(HasDocument),
new PropertyMetadata(new PropertyChangedCallback(DocumentChanged)));
private static void DocumentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("Document has changed");
}
public FlowDocument Document
{
get { return GetValue(DocumentProperty) as FlowDocument; }
set { SetValue(DocumentProperty, value); }
}
}
使用 XAML 中的富文本框创建 Window。
<Window x:Class="samples.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Flow Document Binding" Height="300" Width="300"
>
<Grid>
<RichTextBox Name="richTextBox" />
</Grid>
</Window>
给Window 一个HasDocument 类型的字段。
HasDocument hasDocument;
窗口构造函数应该创建绑定。
hasDocument = new HasDocument();
InitializeComponent();
Binding b = new Binding("Document");
b.Source = richTextBox;
b.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(hasDocument, HasDocument.DocumentProperty, b);
如果您希望能够在 XAML 中声明绑定,则必须使您的 HasDocument 类派生自 FrameworkElement,以便可以将其插入到逻辑树中。
现在,如果您要更改 HasDocument 上的 Document 属性,富文本框的 Document 也会更改。
FlowDocument d = new FlowDocument();
Paragraph g = new Paragraph();
Run a = new Run();
a.Text = "I showed this using a binding";
g.Inlines.Add(a);
d.Blocks.Add(g);
hasDocument.Document = d;