我正在尝试(并且失败)对xaml中的依赖项属性进行数据绑定。当我使用后面的代码时,它工作正常,但不是在xaml中。
用户控件只是绑定到依赖项属性的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
。
private string _myText = "default";
public string MyText
{
get { return _myText; }
set { _myText = value; NotifyPropertyChanged(); }
}
到目前为止一切顺利。如果我将此属性绑定到主窗口上的TextBlock
,一切正常。如果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中运行?
答案 0 :(得分:12)
依赖项属性声明必须如下所示:
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
属性:
<UserControl x:Class="WpfTest.MyControl" ...>
<TextBlock Text="{Binding Test,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</UserControl>
同样非常重要的是,从不在其构造函数中设置UserControl的DataContext
。我确定有类似
DataContext = this;
删除它,因为它有效地阻止从UserConrol的父级继承DataContext。
通过在代码中的Binding中设置Source = DataContext
,您将明确设置绑定源,而在
<local:MyControl Test="{Binding MyText}" />
绑定源隐式是当前的DataContext。但是,DataContext已经由UserControl的构造函数中的赋值设置为UserControl本身,并且不是窗口中继承的DataContext(即视图模型实例)。