XAML绑定不能在依赖项属性上工作? [英] XAML binding not working on dependency property?
问题描述
我正在尝试(并且失败)对xaml中的依赖项属性进行数据绑定。当我在后面使用代码而不是在xaml中时,它工作得很好。
I am trying (and failing) to do data binding on a dependency property in xaml. It works just fine when I use code behind, but not in xaml.
用户控件只是一个 TextBlock
绑定到依赖项属性的对象:
The user control is simply a TextBlock
that bind to the dependency property:
<UserControl x:Class="WpfTest.MyControl" [...]>
<TextBlock Text="{Binding Test}" />
</UserControl>
并且依赖项属性是一个简单的字符串:
And the dependency property is a simple string:
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
。
I have a regular property with the usual implementation of INotifyPropertyChanged
in the main window.
private string _myText = "default";
public string MyText
{
get { return _myText; }
set { _myText = value; NotifyPropertyChanged(); }
}
到目前为止很好。如果我将此属性绑定到主窗口上的 TextBlock
,则一切正常。如果 MyText
发生更改并且世界上一切都很好,则文本将正确更新。
So far so good. If I bind this property to a TextBlock
on the main window everything works just fine. The text update properly if the MyText
changes and all is well in the world.
<TextBlock Text="{Binding MyText}" />
但是,如果我在用户控件上执行相同的操作,则什么也不会发生。
However, if I do the same thing on my user control, nothing happens.
<local:MyControl x:Name="TheControl" Test="{Binding MyText}" />
现在有趣的部分是,如果我在其背后的代码中执行完全相同的绑定,就可以了! / p>
And now the fun part is that if I do the very same binding in code behind it works!
TheControl.SetBinding(MyControl.TestProperty, new Binding
{
Source = DataContext,
Path = new PropertyPath("MyText"),
Mode = BindingMode.TwoWay
});
为什么在xaml中不起作用?
Why is it not working in xaml?
推荐答案
依赖项属性声明必须如下所示:
The dependency property declaration must look like this:
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中的绑定必须将控件实例设置为源对象,例如通过设置绑定的 RelativeSource
属性:
The binding in the UserControl's XAML must set the control instance as the source object, e.g. by setting the Bindings's RelativeSource
property:
<UserControl x:Class="WpfTest.MyControl" ...>
<TextBlock Text="{Binding Test,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</UserControl>
同样非常重要,从不在其构造函数中设置UserControl的 DataContext
。我确定类似
Also very important, never set the DataContext
of a UserControl in its constructor. I'm sure there is something like
DataContext = this;
删除它,因为它有效地防止了从UserConrol的父类继承DataContext。
Remove it, as it effectively prevents inheriting a DataContext from the UserConrol's parent.
通过在后面的绑定代码中设置 Source = DataContext
,您可以显式设置绑定源,而在
By setting Source = DataContext
in the Binding in code behind you are explicitly setting a binding source, while in
<local:MyControl Test="{Binding MyText}" />
绑定源隐式为当前DataContext。但是,该DataContext是通过UserControl的构造函数中对UserControl本身的分配来设置的,而不是从窗口继承的DataContext(即视图模型实例)。
the binding source implicitly is the current DataContext. However, that DataContext has been set by the assignment in the UserControl's constructor to the UserControl itself, and is not the inherited DataContext (i.e. the view model instance) from the window.
这篇关于XAML绑定不能在依赖项属性上工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!