WPF 数据绑定的“RelativeSource FindAncestor”到底是什么?做?
我目前正在 WPF 用户控件中工作(我的 XAML 文件的根元素是“UserControl”),我知道该控件托管在 Window 内。如何使用数据绑定访问窗口的属性?
有谁知道为什么根本
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="..." />
不起作用?我收到的错误消息是:
System.Windows.Data 警告:4:无法找到与引用 'RelativeSource FindAncestor,AncestorType='System.Windows.Window',AncestorLevel='1'' 进行绑定的源。
编辑:我最终使用了 ArsenMkrt 方法的变体,因此接受了他的答案。然而,我仍然有兴趣找出为什么 FindAncestor 不“正常工作”。
I am currently working within a WPF user control (the root element of my XAML file is "UserControl"), which I know is being hosted inside a Window. How can I access a property of the Window using data binding?
Does anyone know why simply
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="..." />
does not work? The error message I get is:
System.Windows.Data Warning: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''.
Edit: I ended up using a variation on ArsenMkrt's approach, so have accepted his answer. However, I am still interested in finding out why FindAncestor does not "just work".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最好的方法是为 UserControl 命名
在 UserControl 中使用两种方式绑定创建依赖属性 MyProperty 并将其绑定在主窗口中,而不是像这样在 UserControl 中绑定
The best way is to give a name to UserControl
Create dependency property MyProperty in UserControl with two way binding and bind it in main Window, than bind in UserControl like this
如果您尝试从
ItemsControl
或DataGridView
中“逃脱”以到达Window
,您可能会发现 AncestorType 为x:Type Window
不起作用。或者至少似乎没有...如果是这种情况,您可能正在运行 Blend 或 Visual Studio 并期望数据在设计时可见 - 但事实并非如此,因为 VS + Blend 都会创建自己的实例那不是真正的Windows。它在运行时可以正常工作,但在设计模式下则不行。
您可以执行以下操作:
包装在 UserControl 中
这是我提出的替代解决方案。它的一个优点是您不直接引用
UserControl
或Window
,因此如果您更改父容器,您的代码不会中断。<前><代码><窗口
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc =“http://schemas.openxmlformats.org/markup-compatibility/2006”
xmlns:views="clr-namespace:MyWPFApplication.Views"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyWPFApplication.Views.UPCLabelPrinterWindow"
mc:可忽略=“d”
x:名称=“布局根”
标题=“UPCLabelPrinterWindow”>
<视图:DataContextWrapper>
...
其中
DataContextWrapper
只是一个网格然后当您绑定时,您可以执行以下操作:
注意:如果您想绑定到 Window 本身的属性,则比较棘手,您可能应该通过依赖属性或类似的东西进行绑定。但如果您使用 MVVM,那么这是我找到的一种解决方案。
If you're trying to 'escape' from an
ItemsControl
orDataGridView
to get to aWindow
you may be finding that AncestorType ofx:Type Window
doesn't work. Or at least doesn't seem to...If this is the case you're probably running Blend or Visual Studio and expecting the data to be visible at design time - which it won't because VS + Blend both create their own instances that aren't really Windows. It will work at runtime just fine, but not during design mode.
There's a couple things you can do:
Wrap in a UserControl
Here's an alternative solution I've come up with. It has one advantage in that you're not referencing a
UserControl
orWindow
directly, so if you change the parent container your code won't break.Where
DataContextWrapper
is just a GridThen when you bind you do this :
Note: if you want to bind to a property ON Window itself it's trickier and you should probably bind via a dependency property or something like that. But if you are using MVVM then this is one solution I found.
如果您使用视图模型作为窗口的 DataContext 并且需要绑定的属性来自该视图模型,那么您应该在路径前加上 DataContext.MyPropertyPath 前缀,如下所示:
这翻译为“为我查找一个祖先窗口,然后查看 MyProperty 的数据上下文”
If you are using a view model as your Window's DataContext and the property you need to bind to is from that view model then you should prefix the path with DataContext.MyPropertyPath, something like this:
this translates as "Find me an ancestor window and then look in it's data context for MyProperty"
我认为你应该像这样设置 Mode="OneWayToSource":
I Think You Should SET Mode="OneWayToSource" Like this: