WPF 附加属性数据绑定
Posted
技术标签:
【中文标题】WPF 附加属性数据绑定【英文标题】:WPF Attached Property Data Binding 【发布时间】:2022-01-14 00:10:15 【问题描述】:我尝试使用带有附加属性的绑定。但不能让它工作。
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 )
,假设 propertyName
是 String
。【参考方案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 附加属性数据绑定的主要内容,如果未能解决你的问题,请参考以下文章
由一次PasswordBox密码绑定引发的疑问 ---; WPF中的附加属性的定义,以及使用。