【问题标题】:AncestorLevel not working when binding to the view model of parent window in WPF绑定到 WPF 中父窗口的视图模型时,AncestorLevel 不起作用
【发布时间】:2016-07-21 20:00:38
【问题描述】:

MainWindow 绑定到MainViewModel,其余的都绑定到ChildViewModel,这是MainViewModel 的一个属性。现在在绑定到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]   -  -  -  -  -
-   -   -   -   -                             -  -  -  -  -
-   -   -   -   -------------------------------  -  -  -  -
-   -   -   --------------------------------------  -  -  -
-   -   ---------------------------------------------  -  -
-   ----------------------------------------------------  -
-----------------------------------------------------------

更新:

我最好的猜测是,一个只能绑定到父窗口并且不能更高。也许最上面的窗口不在可视化树中?

【问题讨论】:

    标签: c# wpf xaml data-binding multibinding


    【解决方案1】:

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

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


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

    Helpful Silverlight Snippets - Jeff Wilcox

    【讨论】:

    • 它没有用。似乎它无法以这种方式识别父窗口。我用它来验证也没有成功。 &lt;Label Content="{Binding ElementName=MyWindowName, Path=Title}" Height="28" /&gt;
    • @Vahid 主窗口如何实例化子窗口?
    • MainWindow 的视图模型在后面的代码中实例化,然后我在MainWindow 中有用户控件,它们的数据上下文在 XAML 中实例化并在代码隐藏中传递给子窗口.到目前为止,除了我无法识别父窗口的问题之外,一切都运行良好。我可以从Child Window 2 中识别出Child Window 1,但没有上层。
    • @Vahid 查看关于在ChildViewModel 上放置属性的更新答案。
    • @Vahid 我相信在子窗口的级别上,它的逻辑树不包括直接路由我们看到的在视觉树中;因此失败了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 2013-09-26
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多