Wpf 从一个视图模型访问另一个视图模型的属性

Wpf 从一个视图模型访问另一个视图模型的属性,wpf,mvvm,properties,viewmodel,Wpf,Mvvm,Properties,Viewmodel,我的WPF应用程序遵循MVVM模式。有三种观点: 主窗口 登录视图 项目视图 LoginView和ProjectsView是由main窗口导入的用户控件。两个视图都指定了其视图模型LoginViewModel定义一个属性ProjectList,该属性通过调用Web服务来设置。现在LoginViewModel需要访问ProjectList属性和其他属性 我知道一个解决方案可能是重新设计,以便只有一个视图和一个视图模型。我会这样做作为一个备份解决方案,但我不赞成这样做 如何做到这一点?我应该

我的WPF应用程序遵循MVVM模式。有三种观点:

  • 主窗口
    • 登录视图
    • 项目视图
LoginView
ProjectsView
是由
main窗口导入的用户控件。两个视图都指定了其视图模型
LoginViewModel
定义一个属性
ProjectList
,该属性通过调用Web服务来设置。现在
LoginViewModel
需要访问
ProjectList
属性和其他属性

我知道一个解决方案可能是重新设计,以便只有一个视图和一个视图模型。我会这样做作为一个备份解决方案,但我不赞成这样做


如何做到这一点?我应该使用类似Prism的事件聚合器吗?或者有其他方法可以做到这一点吗?

因此,如果我理解清楚,
ProjectList
属性应该从“LoginViewModel”和“ProjectsViewModel”访问。我会尝试在“MainViewModel”中实现它,以便子viewmodels可以以自然的方式访问它

IEventAggregator就像一个盒子,你可以在里面添加事件,或者查找和订阅事件,所以我想说这不是你需要的。 无论如何,您可以在
UnitySingleton.Container
中注册自定义界面(框类型),这将公开
ProjectList
,以便在任何地方都可以访问它。当模块是独立的程序集,需要相互通信时,这种方法非常有意义。 如果在您的情况下,这是否是过度的,您应该做出决定,我个人会选择“将其放入mainviewmodel”选项

--样本--(未测试)

正如您所看到的,这非常简单,
LoginVM
ProjectsVM
将包含对创建它们的
MainViewModel
的引用,因此允许它们访问
ProjectList

如何做到这一点?我应该使用某种事件聚合器吗 像棱镜一样?还是有其他方法可以做到这一点

以下是一些想法:

  • 可以创建同时包含两个视图模型的视图模型类 继承自。此基类将包含共享属性
  • 创建包含共享属性的静态类
  • 使用依赖项注入,创建一个包含 属性,将其注册为容器中的单例并注入 将其导入视图模型的构件中

此外,我认为
EventAggregator
最适合于模块/程序集之间的通信。在您的示例中,似乎所有内容都在同一个程序集中。

您能解释一下从ChildVM 1到ChildVM2需要什么类型的访问吗?要修改吗?还是读取?@ryadavilli对于上面的示例,我只需要读取访问权限,即
ProjectViewModel
将从
LoginViewModel
读取
ProjectList
。然而,在进一步的开发过程中,可能会出现类似的情况,需要读写访问。我认为这一段中的问题有一个拼写错误:“LoginView和ProjectsView是由主窗口导入的用户控件。两个视图都指定了其视图模型。LoginViewModel定义了一个属性ProjectList,它是通过调用webservice设置的。现在LoginViewModel需要访问ProjectList属性和其他属性。“感谢您提供的示例。我明白了这个想法。但是,对于视图中的数据绑定(XAML),我仍然不确定。这意味着我会将MainViewModel设置为DataContext?例如,我如何从LoginViewModel访问属性?您的MainWindow的DataContext当然是MainViewModel!然后您可以将MainWindow中的每个视图绑定到MainViewModel中的相应属性。所有这些都完美地连接起来!对
的引用是什么
mean in
LoginVM=new LoginViewModel(this);
?我需要如何为这些类编写构造函数?
public LoginViewModel(MainViewModel mainVM)
?对这两个问题都是,然后您可以访问mainVM中定义的常规属性或命令。这种方法的另一个优点是,您不确定Mainviewmodel是否将成为单例(规格可能会有所不同)。注意第一个想法,子类化将为每个viewmodel提供不同的属性实例。这不是他想要的。
public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        LoginVM = new LoginViewModel(this);
        ProjectsVM = new ProjectsViewModel(this);
        RetrieveProjectList();
    }

    public LoginViewModel LoginVM { get; private set; }

    public ProjectsViewModel ProjectsVM { get; private set; }

    public object ProjectList { get; private set; }

    private void RetrieveProjectList()
    {
        ProjectList = ....
    }
}