将 TabItem 数据绑定到父级 Window

Databinding a TabItem to a parent Window

我正在尝试清理我将 DataContext 与我的 UserControl 一起使用的方式,目前 运行 我遇到了一个问题,我需要将 TabItem 内的 UserControl 数据绑定到父级 Window 的数据上下文。

这是我的 Window 的草图:

如您所见,此 Window 拥有一个 TabControl,其中包含通过 "Tabs" ItemSource 动态添加的 TabItem。此时的数据绑定工作正常,因为 "Tabs" 填充了选项卡 1。

Tab 1 包含一个 UserControl,它需要访问 DiagnosticsViewModel 中的多个字符串属性,但是当我 运行 我的应用程序时,输出 window 表明所有绑定都失败了。例如:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=Property1; DataItem=null; target element is 'Tab1UserControl' (Name=''); target property is 'UCName' (type 'String')

选项卡 1 中用户控件的 XAML 看起来像这样:

<Grid>
    <uc:Tab1UserControl UCName="{Binding Property1, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</Grid>

其中 UCName 是字符串 DependencyProperty。

如果我告诉 WPF 我想查找树并绑定到最近的 Window 的 DataContext,而我的 Window 的 DataContext 设置为 DiagnosticsViewModel,为什么'它不是将它用于我的 UserControl 的 DataContext 吗?我没有在我的 UserControl 中设置 DataContext = this,因为我过去曾多次不正确地设置,期望我的 UserControl 能够从其父级继承 DataContext。

我想看看 Snoop 是否可以解决我的问题,但是这个 GUI 是从 MFC 应用程序显示的,而且 Snoop 似乎无法附加到我的 WPF 对话框。

如果您使用 RelativeSource、ElementName 等更改绑定源,则绑定将直接指向您指定的元素,而不是其数据上下文。这意味着在您的代码中,用户控件将尝试绑定到 Diagnostics class 本身上名为 Property1 的 属性。

尝试使用

<Grid>
    <uc:Tab1UserControl UCName="{Binding Path=DataContext.Property1, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</Grid>

在用户控件的代码中查看是否可以解决问题。

(顺便说一句,用户控件本身知道它所属的 window 将具有给定 属性 的数据上下文的想法对我来说似乎是一种代码味道,特别是因为用户控件的要点是它们是可重用的 - 对用户控件有依赖性 属性 感觉更好,然后在您使用它时将其绑定到适当的 属性。这可能只是不过是因为我缺乏上下文。)