WPF数据绑定&x27;s";相对资源查找器“;做
我目前在一个WPF用户控件(我的XAML文件的根元素是“UserControl”)中工作,我知道该控件托管在一个窗口中。如何使用数据绑定访问窗口的属性 有人知道为什么吗WPF数据绑定&x27;s";相对资源查找器“;做,wpf,data-binding,xaml,relativesource,findancestor,Wpf,Data Binding,Xaml,Relativesource,Findancestor,我目前在一个WPF用户控件(我的XAML文件的根元素是“UserControl”)中工作,我知道该控件托管在一个窗口中。如何使用数据绑定访问窗口的属性 有人知道为什么吗 <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="..." /> 不起作用?我收到的错误消息是: System.Windows.Data警告:4:找不到引用为“RelativeS
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="..." />
不起作用?我收到的错误消息是:
System.Windows.Data警告:4:找不到引用为“RelativeSource FindAncestor,AncestorType='System.Windows.Window',AncestorLevel='1'的绑定源
编辑:我最终使用了阿森姆克特方法的变体,所以我接受了他的答案。然而,我仍然有兴趣找出为什么FindAncestor不“只工作”。最好的方法是给UserControl命名 使用双向绑定在UserControl中创建依赖项属性MyProperty,并在主窗口中绑定它,而不是像这样在UserControl中绑定
<UserControl x:Name = "myControl">
<Label Content={Binding ElementName= myControl, Path=MyProperty}/>
</UserControl>
我认为您应该像这样设置Mode=“OneWayToSource”:
<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor ,AncestorType={x:Type Grid}},Path=BackGround , Mode=OneWayToSource , UpdateSourceTrigger = PropertyChanged}" />
如果您试图从
ItemsControl
或DataGridView
中“转义”到窗口
中,您可能会发现x:Type Window
的取消存储类型不起作用。或者至少看起来没有
如果是这种情况,您可能正在运行Blend或Visual Studio,并希望数据在设计时可见,但事实并非如此,因为VS+Blend都创建了自己的实例,而这些实例并不是真正的Windows。它可以在运行时正常工作,但不能在设计模式下工作
你可以做几件事:
- 包装在用户控件中
- 这是我想出的另一个解决办法。它的一个优点是,您没有直接引用
或用户控件
,因此,如果更改父容器,代码不会中断窗口
然后在绑定时执行以下操作:<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:Ignorable="d" x:Name="LayoutRoot" Title="UPCLabelPrinterWindow"> <views:DataContextWrapper> <DockPanel> ... </DockPanel> </views:DataContextWrapper>
<TextBlock Text="{Binding="{Binding DataContext.SomeText, RelativeSource={RelativeSource AncestorType={x:Type views:DataContextWrapper}, Mode=FindAncestor}}" />
如果使用视图模型作为窗口的DataContext,并且需要绑定到的属性来自该视图模型,则应在路径前面加上DataContext.MyPropertyPath前缀,如下所示:
<TextBox Text="{Binding DataContext.MyProperty, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}"/>
这可以翻译为“为我找到一个祖先窗口,然后在它的数据上下文中查找MyProperty”,但我想绑定到包含窗口上的属性(在另一个XAML文件中定义),不在UserControl上。在UserControl中有属性并将该属性与窗口的属性绑定会更好。可以在UserControl中创建依赖项属性吗?您不在窗口中添加用户控件吗?我明白了,谢谢。但有人知道为什么FindAncestor不“只是工作”吗?它的范围是否在某种程度上受到限制,比如说,限制在单个XAML文件中?老实说,我不知道为什么它不起作用,但是我的答案是更好的解决方案,因为父类型可以在开发期间更改。您说您更改了他的答案,请注意,我正在MVVM模式的上下文中寻找这个问题的解决方案。我想要绑定到的窗口的属性实际上是窗口的ViewModel的属性。ArsenMkrt建议在UserControl中创建一个属性并绑定到该属性,然后反过来(在XAML中)将该属性绑定到窗口的所需属性。然而,在MVVM模式中,UserControl从未出现在XAML中,因此第二部分不可能出现。因此,我按照建议创建一个新的绑定属性,但不是将其放在UserControl中,而是将其放在UserControl的ViewModel中。此属性仅包含对窗口的ViewModel的直接引用,允许直接访问所需的属性。新属性很容易初始化:要使用的引用可以直接传递到UserControl的ViewModel的构造函数中。在我的例子中,
非常有用,因为AncestorType={x:Type Window}
虽然通常指向我的窗口,但它并没有指向我的窗口。AncestorType=UserControl
<TextBox Text="{Binding DataContext.MyProperty, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}"/>