在 WPF 中绑定到 parent window 的视图模型时,AncestorLevel 不起作用

AncestorLevel not working when binding to the view model of parent window in WPF

MainWindow 绑定到 MainViewModel,其余的都绑定到 ChildViewModel,这是 MainViewModel 的 属性。现在最里面的childwindow绑定了ChildViewModel,我想绑定一个属性到MainViewModel.

我正在使用以下代码:

此处 Converter 的第一个值绑定到 ChildViewModel 中的 属性 C 并且有效。我试图将第二个值绑定到 属性 到 MainWindow (MainViewModel) 的 DataContext 但没有成功。

<MultiBinding Converter="{StaticResource UnitConverter}">
    <Binding Path="C"/>
    <Binding RelativeSource="{RelativeSource FindAncestor, 
        AncestorType={x:Type Window}, AncestorLevel=2}"
             Path="DataContext.CurrentTargetUnit"/>
</MultiBinding>

--- Main Window -------------------------------------------
-   ----- User Control 1 -------------------------------  -
-   -   ---- User Control 2--------------------------  -  -
-   -   -   ------ Child Window 1 ----------------  -  -  -
-   -   -   -   ----- Child Window 2 ----------  -  -  -  -
-   -   -   -   -                             -  -  -  -  -
-   -   -   -   -   [Bind to MainViewModel]   -  -  -  -  -
-   -   -   -   -                             -  -  -  -  -
-   -   -   -   -------------------------------  -  -  -  -
-   -   -   --------------------------------------  -  -  -
-   -   ---------------------------------------------  -  -
-   ----------------------------------------------------  -
-----------------------------------------------------------

更新:

我最好的猜测是只能绑定到 parent window 并且不能高于此。也许最上面的 window 不在可视化树中?

ChildViewModel 上创建一个 属性,它是对 MainViewModel 的引用 link。在子 VM 实例化后,link 它到 MainViewModel。然后内部 windows/controls 可以通过引用上述 ChildViewModel 属性 到主虚拟机来到达 MainViewModel


在用户控件 1 和 2 上创建主视图模型类型的依赖项 属性,例如:

// <summary>
/// Holds the parent VM here.
/// </summary>
public MainVM ParentVM
{
    get { return GetValue(ParentVMProperty) as MainVM; }
    set { SetValue(ParentVMProperty, value); }
}

    /// <summary>
    /// Identifies the ParentVM dependency property.
    /// </summary>
    public static readonly System.Windows.DependencyProperty ParentVMProperty =
        System.Windows.DependencyProperty.Register(
            "ParentVM",
            typeof(MainVM),
            typeof({Insert Control1 or 2 class type here}),
            new System.Windows.PropertyMetadata(null, OnParentVMPropertyChanged));

    /// <summary>
    /// ParentVMProperty property changed handler.
    /// </summary>
    /// <param name="d">BeginRandom that changed its ParentVM.</param>
    /// <param name="e">Event arguments.</param>
    private static void OnParentVMPropertyChanged(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs e)
    {
        var source = d as {Insert Control1 or 2 class type here};
        MainVM value = e.NewValue as MainVM;
    }

由于每个 window 都将有一个对 MainWindowVM 可用的引用,您所要做的就是指向当前 window 的 ParentVM 属性 的路径。


请注意,为了创建控件的依赖属性,我使用了为 Silverlight 编写的方便的片段,但是所有这些 都可以在 WPF 中工作:

Helpful Silverlight Snippets - Jeff Wilcox