我正在尝试(并且失败)对xaml中的依赖项属性进行数据绑定。当我在后面使用代码时,它工作得很好,但在xaml中却不能。
用户控件只是一个TextBlock绑定到依赖项属性的控件:
TextBlock
<UserControl x:Class="WpfTest.MyControl" [...]> <TextBlock Text="{Binding Test}" /> </UserControl>
依赖属性是一个简单的字符串:
public static readonly DependencyProperty TestProperty = DependencyProperty.Register("Test", typeof(string), typeof(MyControl), new PropertyMetadata("DEFAULT")); public string Test { get { return (string)GetValue(TestProperty); } set { SetValue(TestProperty, value); } }
我有一个常规属性,INotifyPropertyChanged在主窗口中具有通常的实现。
INotifyPropertyChanged
private string _myText = "default"; public string MyText { get { return _myText; } set { _myText = value; NotifyPropertyChanged(); } }
到目前为止,一切都很好。如果我将此属性绑定到TextBlock主窗口上的,则一切正常。如果MyText更改已全部完成,则文本将正确更新。
MyText
<TextBlock Text="{Binding MyText}" />
但是,如果我在用户控件上执行相同的操作,则什么也不会发生。
<local:MyControl x:Name="TheControl" Test="{Binding MyText}" />
现在有趣的部分是,如果我在背后的代码中进行完全相同的绑定,它将起作用!
TheControl.SetBinding(MyControl.TestProperty, new Binding { Source = DataContext, Path = new PropertyPath("MyText"), Mode = BindingMode.TwoWay });
为什么在xaml中不起作用?
依赖项属性声明必须如下所示:
public static readonly DependencyProperty TestProperty = DependencyProperty.Register( "Test", typeof(string), typeof(MyControl), new PropertyMetadata("DEFAULT")); public string Test { get { return (string)GetValue(TestProperty); } set { SetValue(TestProperty, value); } }
UserControl的XAML中的绑定必须将控件实例设置为源对象,例如通过设置Bindings的RelativeSource属性:
RelativeSource
<UserControl x:Class="WpfTest.MyControl" ...> <TextBlock Text="{Binding Test, RelativeSource={RelativeSource AncestorType=UserControl}}"/> </UserControl>
同样非常重要, 永远不要DataContext在其构造函数中设置UserControl的。我肯定有类似的东西
DataContext
DataContext = this;
删除它,因为它有效地防止了从UserConrol的父类继承DataContext。
通过Source = DataContext在后面的“绑定中的代码”中进行设置,您可以显式设置绑定源,而在
Source = DataContext
<local:MyControl Test="{Binding MyText}" />
绑定源隐式为当前DataContext。但是,该DataContext是通过UserControl的构造函数中对UserControl本身的分配来设置的,而不是从窗口继承的DataContext(即视图模型实例)。