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}" />
现在有趣的部分是,如果我在其背后的代码中执行相同的绑定工作!
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(
nameof(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屋!