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

Posted

技术标签:

【中文标题】XAML 绑定不适用于依赖属性?【英文标题】:XAML binding not working on dependency property? 【发布时间】:2017-03-04 05:03:17 【问题描述】:

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

【问题讨论】:

显示更多 XAML。我怀疑如果你绑定到 Binding,你会发现你绑定到了错误的数据上下文。 您应该将属性名称(“Test”)作为第一个参数传递给 Register 方法。我找不到接收 Type 作为第一个参数的重载。 MyControl 的 DataContext 是什么?它应该是主窗口 如果数据上下文错误,它也无法与解决方案背后的代码一起使用。 DataContext 在两个构造函数(窗口和用户控件)中都设置为 this 是的,我已经尝试过RegisterAttached。不幸的是,它也不起作用。 【参考方案1】:

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

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 属性:

<UserControl x:Class="WpfTest.MyControl" ...>
     <TextBlock Text="Binding Test,
         RelativeSource=RelativeSource AncestorType=UserControl"/>
</UserControl>

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

DataContext = this;

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

通过在 Binding in 后面的代码中设置 Source = DataContext 来显式设置绑定源,而在

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

绑定源隐含地是当前 DataContext。但是,该 DataContext 已由 UserControl 的构造函数中的赋值设置为 UserControl 本身,而不是从窗口继承的 DataContext(即视图模型实例)。

【讨论】:

恐怕没用。顺便说一句,您为DependencyProperty 编写的声明与我的问题完全相同。 远非完全一样。在您的问题中,您忘记了属性名称(“Test”)和 PropertyMetadata 上的 new 关键字。这些细节很重要! 天哪,你完全正确!我非常抱歉。我一定是贴错了代码。 查看我关于在 UserControl 的 ctor 中设置 DataContext 的更新答案。你不能那样做! DataContext = this; 包含此内容的教程普遍由 trolling assholes 编写。

以上是关于XAML 绑定不适用于依赖属性?的主要内容,如果未能解决你的问题,请参考以下文章

将字符串项绑定到 xaml 中字符串的依赖属性列表

绑定到 UserControl XAML 中的依赖属性

WPF ----在UserControl的xaml里绑定依赖属性

为啥在数据模板中使用 xaml UserControl 时无法绑定到依赖属性? [复制]

将 GeometryDrawing 画笔绑定到自定义控件依赖属性

什么是依赖项属性?(在练习使用StoryBoard故事板时,遇到的问题)