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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14357049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 07:03:54  来源:igfitidea点击:

Access properties from one view model in another

wpfmvvmpropertiesviewmodel

提问by Robert Strauch

My WPF application follows the MVVM pattern. There are three views:

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

  • MainWindow
    • LoginView
    • ProjectsView
  • 主窗口
    • 登录视图
    • 项目视图

LoginViewand ProjectsVieware user controls imported by the MainWindow. Both views have their view model assigned. LoginViewModeldefines a property ProjectListwhich is set by calling a webservice. Now LoginViewModelneeds access to the ProjectListproperty and others.

LoginViewProjectsView是由MainWindow. 两个视图都分配了视图模型。LoginViewModel定义ProjectList通过调用 web 服务设置的属性。现在LoginViewModel需要访问该ProjectList属性和其他。

I am aware that one solution might be a redesign so that there is only one view and one view model. I would do that as a backup solution but I would favor not to do so.

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

How should this be done? Should I use some kind of EventAggregator like in Prism? Or are there other ways to do this?

这应该怎么做?我应该在 Prism 中使用某种 EventAggregator 吗?或者还有其他方法可以做到这一点?

回答by Natxo

So if i understood clearly, ProjectListproperty should be accessed from both 'LoginViewModel' and 'ProjectsViewModel'. I'd try to implement it in the 'MainViewModel' so child viewmodels can access it in a natural way.

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

An IEventAggregator is like a box in which you can add events, or find and subscribe to one, so i would say it's not what you need. Anyway, you could register your custom interface (box type) in the UnitySingleton.Container, which would expose ProjectListfor it to be accessible everywhere. This approach makes a lot of sense when modules, which are separate assemblies, need to communicate whith each other. If this is overkill or not in your case is something you should decide, i'd personally go with the 'put it in the mainviewmodel' option.

IEventAggregator 就像一个盒子,您可以在其中添加事件,或查找和订阅事件,所以我会说这不是您所需要的。无论如何,您可以在 中注册您的自定义接口(框类型)UnitySingleton.Container,这将ProjectList使其在任何地方都可以访问。当作为独立程序集的模块需要相互通信时,这种方法很有意义。如果这在您的情况下是否矫枉过正是您应该决定的事情,我个人会选择“将其放入主视图模型”选项。

-- Sample --(not tested)

-- 样品 --(未测试)

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 = ....
    }
}

It's pretty simple as you see, LoginVMand ProjectsVMwill hold a reference to the MainViewModelthat created them, therefore giving them access to ProjectList.

如您所见,它非常简单,LoginVM并且ProjectsVM将保存对MainViewModel创建它们的的引用,因此允许它们访问ProjectList.

回答by Big Daddy

How should this be done? Should I use some kind of EventAggregator like in Prism? Or are there other ways to do this?

这应该怎么做?我应该在 Prism 中使用某种 EventAggregator 吗?或者还有其他方法可以做到这一点?

Here are a few ideas:

这里有一些想法:

  • You can create a view-model class that both view-models inherit from. This base class will contain the shared properties.
  • Create a static class that contains the shared properties.
  • Using dependency injection, create a class that contains the properties, register it as a singleton in your container and inject it into your view-model's ctors.
  • 您可以创建两个视图模型都继承的视图模型类。该基类将包含共享属性。
  • 创建一个包含共享属性的静态类。
  • 使用依赖注入,创建一个包含属性的类,将其注册为容器中的单例并将其注入到视图模型的构造函数中。

Also, I believe that the EventAggregatoris best suited for communicating between modules/assemblies. In your example, it seems like everything is in the same assembly.

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