XAML绑定不依赖于依赖属性?

Oli*_*ver 5 c# data-binding wpf xaml dependency-properties

我正在尝试(并且失败)在xaml中对依赖项属性进行数据绑定.当我使用代码后,它工作正常,但不是在xaml中.

用户控件只是一个TextBlock绑定到依赖属性的控件:

<UserControl x:Class="WpfTest.MyControl" [...]>
     <TextBlock Text="{Binding Test}" />
</UserControl>
Run Code Online (Sandbox Code Playgroud)

而dependency属性是一个简单的字符串:

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); }
}
Run Code Online (Sandbox Code Playgroud)

我有一个常规属性与INotifyPropertyChanged主窗口中的常规实现.

private string _myText = "default";
public string MyText
{
   get { return _myText; }
   set {  _myText = value; NotifyPropertyChanged(); }
}
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.如果我将此属性绑定到TextBlock主窗口上的一切,一切正常.如果MyText更改和所有内容都在世界范围内,则文本会正确更新.

<TextBlock Text="{Binding MyText}" />
Run Code Online (Sandbox Code Playgroud)

但是,如果我在用户控件上执行相同的操作,则不会发生任何事情.

<local:MyControl x:Name="TheControl" Test="{Binding MyText}" />
Run Code Online (Sandbox Code Playgroud)

现在有趣的是,如果我在代码背后执行相同的绑定,它就可以了!

TheControl.SetBinding(MyControl.TestProperty, new Binding
{
    Source = DataContext,
    Path = new PropertyPath("MyText"),
    Mode = BindingMode.TwoWay
});
Run Code Online (Sandbox Code Playgroud)

为什么它不能在xaml中运行?

Cle*_*ens 15

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

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); }
}
Run Code Online (Sandbox Code Playgroud)

UserControl的XAML中的绑定必须将控件实例设置为源对象,例如通过设置Bindings的RelativeSource属性:

<UserControl x:Class="WpfTest.MyControl" ...>
     <TextBlock Text="{Binding Test,
         RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

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

DataContext = this;
Run Code Online (Sandbox Code Playgroud)

删除它,因为它有效地阻止从UserConrol的父级继承DataContext.

通过设置Source = DataContext后面的代码中的Binding,您可以显式设置绑定源

<local:MyControl Test="{Binding MyText}" />
Run Code Online (Sandbox Code Playgroud)

隐式的绑定源是当前的DataContext.但是,DataContext已经由UserControl的构造函数中的赋值设置为UserControl本身,并且不是窗口中继承的DataContext(即视图模型实例).

  • `DataContext = this;`包含它的教程是通过拖钓混蛋普遍编写的. (5认同)