WPF 附加属性数据绑定

Posted

技术标签:

【中文标题】WPF 附加属性数据绑定【英文标题】:WPF Attached Property Data Binding 【发布时间】:2011-08-15 11:44:29 【问题描述】:

我尝试使用带有附加属性的绑定。但不能让它工作。

public class Attached

    public static DependencyProperty TestProperty =
        DependencyProperty.RegisterAttached("TestProperty", typeof(bool), typeof(Attached),
        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Inherits));

    public static bool GetTest(DependencyObject obj)
    
        return (bool)obj.GetValue(TestProperty);
    

    public static void SetTest(DependencyObject obj, bool value)
    
        obj.SetValue(TestProperty, value);
    

XAML 代码:

<Window ...>
    <StackPanel local:Attached.Test="true" x:Name="f">
        <CheckBox local:Attached.Test="true" IsChecked="Binding (local:Attached.Test), Mode=TwoWay, RelativeSource=RelativeSource Self" />
        <CheckBox local:Attached.Test="true" IsChecked="Binding (local:Attached.Test), Mode=TwoWay" />
    </StackPanel>
</Window>

还有绑定错误:

System.Windows.Data Error: 40 : BindingExpression path error: '(local:Attached.Test)' property not found on 'object' ''StackPanel' (Name='f')'. BindingExpression:Path=(local:Attached.Test); DataItem='StackPanel' (Name='f'); target element is 'CheckBox' (Name=''); target property is 'IsChecked' (type 'Nullable`1')

【问题讨论】:

【参考方案1】:

信不信由你,只需添加Path= 并在绑定到附加属性时使用括号:

IsChecked="Binding Path=(local:Attached.Test), Mode=TwoWay, RelativeSource=RelativeSource Self"

此外,您对RegisterAttached 的调用应传入“Test”作为属性名称,而不是“TestProperty”。

【讨论】:

我已经尝试过了,但遇到了一个例外:Der Eigenschaftspfad ist ungültig。 \"附加\" besitzt keine öffentliche Eigenschaft mit dem Namen \"Test\"。 --> Engl: 属性路径无效。 “附加”不拥有公共财产“测试” RegisterAttached 调用应该通过“Test”,而不是“TestProperty”作为属性名称。 我希望我能多次投票。确保在进行此更改后重建项目。我第一次忘记了,还以为 Path= 没有用。 为什么需要括号?应该阅读什么参考资料才能了解这些神秘的东西? 括号只是附加属性系统中的“索引器”。这就是 WPF 区分附加属性和直接属性的方式。我想编译器会很困惑,无法尝试找出哪些属性是附加的,哪些不是,所以使用括号提供了这个提示。如果您好奇,实际上,WPF 会为附加属性创建一个 PropertyPath,如下所示:new PropertyPath("(0)", new object[] propertyName ),假设 propertyNameString【参考方案2】:

我更愿意将此作为对 Kent 回答的评论发布,但由于我没有足够的代表这样做......只是想指出从 WPF 4.5 开始,添加 Path= 不是不再需要了。但是附加的属性名称仍然需要用括号括起来。

【讨论】:

我自己只是想发表评论,没想到这是 WPF 4.5 及更高版本的功能...很高兴知道,谢谢! 不知道为什么,但是如果我不添加 Path= 并且我正在运行 WPF 4.5 我正在运行 Win 8.1,WPF 会崩溃 老兄,你真的拯救了我的一天。非常感谢。我使用 .net 4.0 并且没有 Path=(...) 它根本不起作用。 .NET 4.8.2 here - 由于某些奇怪的原因,在某些嵌套自定义控件中绑定到附加属性在 某些 情况下有效,但并非总是如此。添加Path= 只是解决了我在 10 小时内无法解决的问题。来自PresentationTraceSources 之类的...property not found... 的消息也不见了。血腥的 WPF 魔法。每当绑定到控件模板中的附加属性时,我都会使用Path=。也许是因为没有 Path,Binding 在绑定构造函数中而不是在 Path 属性设置器中设置 Path 槽?【参考方案3】:

放置一个括号有效。我必须将父 contentcontrol 自动绑定到 datatemplate 中的 textblock。自动化 ID 是附加属性。

我将属性放在括号中并且绑定有效。

AutomationProperties.AutomationId="Binding RelativeSource=RelativeSource Mode=FindAncestor,AncestorType=ContentControl,Path=(AutomationProperties.AutomationId)" 

【讨论】:

以上是关于WPF 附加属性数据绑定的主要内容,如果未能解决你的问题,请参考以下文章

WPF -- PasswordBox数据绑定方法

WPF -- PasswordBox数据绑定方法

由一次PasswordBox密码绑定引发的疑问 ---; WPF中的附加属性的定义,以及使用。

具有依赖属性绑定到 DockPanel.Dock 附加属性的 WPF 自定义控件不起作用

从代码绑定到 WinRT/UWP 中的自定义附加属性

WPF 10天修炼 第十天- WPF数据绑定