对话框相对源绑定(MVVM)

本文关键字:MVVM 绑定 相对 对话框 | 更新日期: 2023-09-27 17:49:18

我有一个WPF对话框,我正试图访问所有者的ViewModel中的属性。

我已经尝试了以下,但它绑定到对话框的ViewModel:

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
        AncestorType={x:Type Window}}, Path=DataContext.Property}"/>

我也试过:

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
        AncestorType={x:Type Window}}, Path=Owner.DataContext.Property}"/>

但是它给出了相同的结果。

生成对话框的代码用户是:
        var dialog = new Dialog(DialogViewModel)
        {
            Owner = Window.GetWindow(this)
        };

我在StackOverflow中看到了几个问题,但似乎没有一个工作。

任何想法?有可能在对话框中有一个相对源吗?

对话框相对源绑定(MVVM)

如果我明确地在子窗口上设置Owner,这对我来说是有效的:

<ComboBox 
    ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Owner.DataContext.Property}"/>

然而:有一个重要的警告,我认为这可能是你所拥有的问题:如果子窗口是父窗口的私有成员,我在显示子窗口之前设置了所有者,它试图在显示子窗口之前解决绑定。此时Owner为空,并且当稍后再次设置Owner时,它不会再次尝试。

但是,如果我在显示子窗口的方法中创建子窗口的新实例,设置Owner,然后在其上调用ShowDialog(),则绑定将正确解析为Owner的非空值。我有理由相信这样做的原因是所有者不是一个DependencyProperty,也不会引发PropertyChanged,所以没有发生任何事情来导致任何更新发生以响应所有者更改的值。如果我在一个窗口的新实例上设置它,而UI线程阻塞在一个事件处理程序上,那么新的窗口实例不会得到周围做任何绑定,直到它的所有者设置之后。但如果我更早创建它,然后让UI线程运行,那就太晚了。

这不是你想要的东西。

我的建议:

给你的子窗口设置如下属性:

#region OwnerDataContext Property
public Object OwnerDataContext
{
    get { return (Object)GetValue(OwnerDataContextProperty); }
    set { SetValue(OwnerDataContextProperty, value); }
}
public static readonly DependencyProperty OwnerDataContextProperty =
    DependencyProperty.Register("OwnerDataContext", typeof(Object), typeof(SubWindow),
        new PropertyMetadata(null));
#endregion OwnerDataContext Property

当你显示子窗口时…

var dialog = new Dialog(DialogViewModel)
{
    Owner = Window.GetWindow(this),
    OwnerDataContext = DataContext
};

作为一个DependencyProperty,绑定将正确地与它交互。所有者窗口可以随意设置它,您可以绑定它。绑定的工作方式是duck-typed,所以对于绑定来说,OwnerDataContext声明了Object类型一点也不重要。反正都是反射。

<ComboBox 
    ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=OwnerDataContext.Property}"/>

我可能完全错了为什么你的代码不能工作,但我打赌这将在任何情况下工作。

wpf+mvvm+Shell启动项目+多个子模块,当你想在子模块的视图模型中写入一些数据时,可能称为SubModuleA,将被sheel作为dll调用。

在SubModuleA中,当你想要将数据写入SubModuleA/resource/data/JsonData等子模块的资源文件时。

在SubModuleA的viewmodel中,相对文件路径为

string jsonFilePath= "../../../SubModuleA/Resource/JsonData/JsonData.json";