WPF Data Binding的“RelativeSource FindAncestor”究竟做了什么?

时间:2009-10-28 11:56:30

标签: wpf data-binding xaml relativesource findancestor

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

有没有人知道为什么只是

<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="..." />

不起作用?我得到的错误信息是:

System.Windows.Data警告:4:无法找到绑定源,引用'RelativeSource FindAncestor,AncestorType ='System.Windows.Window',AncestorLevel ='1''。

编辑:我最终使用了ArsenMkrt方法的变体,所以接受了他的回答。但是,我仍然有兴趣找出为什么FindAncestor不“只是工作”。

4 个答案:

答案 0 :(得分:18)

最好的方法是给UserControl命名

在UserControl中创建依赖属性MyProperty,使用双向绑定并将其绑定在主窗口中,而不是像这样在UserControl中绑定

<UserControl x:Name = "myControl">
     <Label Content={Binding ElementName= myControl, Path=MyProperty}/>
</UserControl>

答案 1 :(得分:4)

如果您试图从ItemsControlDataGridView“逃离”以获得Window,您可能会发现x:Type Window的祖先类型不起作用。或者至少似乎没有......

如果是这种情况,你可能正在运行Blend或Visual Studio并期望数据在设计时可见 - 这不会因为VS + Blend都创建了自己的实例,而不是真正的Windows。它会在运行时很好地工作,但不能在设计模式下工作。

你可以做几件事:

  • 包装UserControl

  • 这是我提出的另一种解决方案。它有一个优点,就是您没有直接引用UserControlWindow,因此如果您更改父容器,您的代码就不会中断。

    <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>
    

DataContextWrapper只是一个网格

namespace MyWPFApplication.Views {
   public class DataContextWrapper : Grid
   {

   }
}

然后当你绑定时,你这样做:

<TextBlock Text="{Binding="{Binding DataContext.SomeText, 
  RelativeSource={RelativeSource AncestorType={x:Type views:DataContextWrapper}, 
  Mode=FindAncestor}}" />

注意:如果你想绑定到一个属性ON Window本身就比较棘手,你应该通过依赖属性或类似的东西进行绑定。但是如果你使用的是MVVM,那么这就是我找到的一个解决方案。

答案 2 :(得分:1)

我认为你应该设置模式=“OneWayToSource”像这样:

<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor ,AncestorType={x:Type Grid}},Path=BackGround , Mode=OneWayToSource , UpdateSourceTrigger = PropertyChanged}" />

答案 3 :(得分:0)

如果您正在使用视图模型作为Window的DataContext,并且您需要绑定到的属性来自该视图模型,则应在路径前加上DataContext.MyPropertyPath,如下所示:

<TextBox Text="{Binding DataContext.MyProperty, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}"/>

这翻译为“找到祖先窗口,然后在MyProperty的数据上下文中查找”