WPF数据绑定&x27;s";相对资源查找器“;做

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

我目前在一个WPF用户控件(我的XAML文件的根元素是“UserControl”)中工作,我知道该控件托管在一个窗口中。如何使用数据绑定访问窗口的属性

有人知道为什么吗

<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}}"/>