绑定到WPF中父窗口的视图模型时,AncestorLevel不起作用

本文关键字:模型 AncestorLevel 不起作用 视图 WPF 窗口 绑定 | 更新日期: 2023-09-27 17:58:03

MainWindow被绑定到MainViewModel,其余的都被绑定到作为MainViewModel属性的ChildViewModel。现在,在绑定到ChildViewModel的最里面的子窗口中,我想将一个属性绑定到MainViewModel

我使用以下代码:

这里,Converter的第一个值绑定到ChildViewModel中的属性C,并且它起作用。我尝试将第二个值绑定到MainWindowMainViewModel)的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]   -  -  -  -  -
-   -   -   -   -                             -  -  -  -  -
-   -   -   -   -------------------------------  -  -  -  -
-   -   -   --------------------------------------  -  -  -
-   -   ---------------------------------------------  -  -
-   ----------------------------------------------------  -
-----------------------------------------------------------

更新:

我的最佳猜测是,只能绑定到父窗口,并且不能高于该值。也许最上面的窗口不在视觉树中?

绑定到WPF中父窗口的视图模型时,AncestorLevel不起作用

ChildViewModel上创建一个属性,该属性是指向MainViewModel的引用链接。在实例化子VM之后,将其链接到MainViewModel。然后,内部窗口/控件可以通过将前面提到的ChildViewModel属性引用到主vm来访问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;
    }

由于每个窗口都有一个可用于MainWindowVM的引用,所以您所要做的就是当前窗口的ParentVM属性的路径。


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

有用的Silverlight代码段-Jeff Wilcox