WPF 数据绑定的“RelativeSource FindAncestor”到底是什么?做?

发布于 2024-08-10 01:33:59 字数 498 浏览 14 评论 0原文

我目前正在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你穿错了嫁妆 2024-08-17 01:33:59

最好的方法是为 UserControl 命名

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

<UserControl x:Name = "myControl">
     <Label Content={Binding ElementName= myControl, Path=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

<UserControl x:Name = "myControl">
     <Label Content={Binding ElementName= myControl, Path=MyProperty}/>
</UserControl>
如梦初醒的夏天 2024-08-17 01:33:59

如果您尝试从 ItemsControlDataGridView 中“逃脱”以到达 Window,您可能会发现 AncestorType 为 x:Type Window 不起作用。或者至少似乎没有...

如果是这种情况,您可能正在运行 Blend 或 Visual Studio 并期望数据在设计时可见 - 但事实并非如此,因为 VS + Blend 都会创建自己的实例那不是真正的Windows。它在运行时可以正常工作,但在设计模式下则不行。

您可以执行以下操作:

  • 包装在 UserControl 中

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

    <前><代码><窗口
    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 只是一个网格

namespace MyWPFApplication.Views {
   public class DataContextWrapper : Grid
   {

   }
}

然后当您绑定时,您可以执行以下操作:

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

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

If you're trying to 'escape' from an ItemsControl or DataGridView to get to a Window you may be finding that AncestorType of x: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 or Window directly, so if you change the parent container your code won't break.

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

Where DataContextWrapper is just a Grid

namespace MyWPFApplication.Views {
   public class DataContextWrapper : Grid
   {

   }
}

Then when you bind you do this :

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

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.

青衫负雪 2024-08-17 01:33:59

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

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

这翻译为“为我查找一个祖先窗口,然后查看 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:

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

this translates as "Find me an ancestor window and then look in it's data context for MyProperty"

起风了 2024-08-17 01:33:59

我认为你应该像这样设置 Mode="OneWayToSource":

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

I Think You Should SET Mode="OneWayToSource" Like this:

<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor ,AncestorType={x:Type Grid}},Path=BackGround , Mode=OneWayToSource , UpdateSourceTrigger = PropertyChanged}" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文