一尘不染

XAML绑定不能在依赖项属性上工作?

c#

我正在尝试(并且失败)对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中不起作用?


阅读 243

收藏
2020-05-19

共1个答案

一尘不染

依赖项属性声明必须如下所示:

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>

同样非常重要, 永远不要DataContext在其构造函数中设置UserControl的。我肯定有类似的东西

DataContext = this;

删除它,因为它有效地防止了从UserConrol的父类继承DataContext。

通过Source = DataContext在后面的“绑定中的代码”中进行设置,您可以显式设置绑定源,而在

<local:MyControl Test="{Binding MyText}" />

绑定源隐式为当前DataContext。但是,该DataContext是通过UserControl的构造函数中对UserControl本身的分配来设置的,而不是从窗口继承的DataContext(即视图模型实例)。

2020-05-19