wpf MVVM:在 ViewModel 之间共享数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16530984/
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 08:47:05  来源:igfitidea点击:

MVVM : Share data between ViewModels

c#wpfdesign-patternsmvvm

提问by Unforgiven

How do I share data between multiple ViewModels ?

如何在多个 ViewModel 之间共享数据?

For example there is a class named Project in application .

例如, application 中有一个名为 Project 的类。

    public class Project : ModelBase
{
    private string _projectName;

    public string ProjectName
    {
        get { return _projectName; }
        set
        {
            _projectName = value;
            RaisePropertyChanged(() => ProjectName);
        }
    }
}

In multiple ViewModels application should access ActiveProject.
What's the best way to share Project between ViewModels ?

在多个 ViewModels 应用程序应该访问 ActiveProject。
在 ViewModel 之间共享 Project 的最佳方式是什么?

  • Mediator Pattern ? (Messaging)
  • Static object
  • Singleton pattern (If yes how?)
  • 中介模式 ? (消息)
  • 静态对象
  • 单例模式(如果是,如何?)

I've used Messaging before but it needs much codding . For all ViewModels I've to create ActiveProject property and also have to register a messenger to update that.

我以前使用过 Messaging 但它需要很多编码。对于所有的 ViewModel,我必须创建 ActiveProject 属性,并且还必须注册一个 Messenger 来更新它。


I use MVVM Light framework.
Any code example would be appreciated.


我使用 MVVM Light 框架。
任何代码示例将不胜感激。

采纳答案by Erno

I would create a ViewModel that acts as a parent to all the Project ViewModels. (Let's call it Solution)

我将创建一个作为所有项目 ViewModel 的父级的 ViewModel。(我们称之为解决方案)

The Solution ViewModel would have the property ActiveProject and an observable collection of Projects.

解决方案 ViewModel 将具有属性 ActiveProject 和一个可观察的项目集合。

回答by Kevin

I would recommend the Mediator Pattern. I have used an EventAggregator for this type of messaging between VM's before and there is really not much to it.

我会推荐中介者模式。我之前使用过 EventAggregator 来处理 VM 之间的这种类型的消息传递,但实际上并没有什么用。

回答by Luká? Koten

Don't, don't. Don't use singletons this way in your MVVM application. In fact, the Project class should be a model for your ViewModels. Just pass it in vm's constructor. If you really need to share one instance of Project class in multiple vm's, then use factories and some type of cache when constructing view models. If your vm reguires some more information, just create special Model class which will derive from Project (or implement IProject), so you can easilly use interface segregation principle.

不要,不要。不要在 MVVM 应用程序中以这种方式使用单例。实际上,Project 类应该是您的 ViewModel 的模型。只需在 vm 的构造函数中传递它。如果你真的需要在多个虚拟机中共享一个 Project 类的实例,那么在构建视图模型时使用工厂和某种类型的缓存。如果您的虚拟机需要更多信息,只需创建将从 Project 派生(或实现 IProject)的特殊 Model 类,这样您就可以轻松使用接口隔离原则。

回答by MotoSV

You could have a static collection which your view model populate before you navigate to the new view model. The target view model can then retrieve the data from within it's constructor.

在导航到新的视图模型之前,您可以拥有一个静态集合,您的视图模型会填充该集合。然后目标视图模型可以从它的构造函数中检索数据。

For example ViewModel1 (VM1) will create a Project and populate it. VM1 will then put the Project into a shard, static, collection. VM1 will then navigate to another view model (VM2). In the constructor of VM2 you would go to the collection and retrieve the Project placed in there by VM1.

例如 ViewModel1 (VM1) 将创建一个项目并填充它。然后,VM1 会将项目放入一个静态分片集合中。VM1 然后将导航到另一个视图模型 (VM2)。在 VM2 的构造函数中,您将转到集合并检索 VM1 放置在其中的项目。

If you used a dictionary of key-value pairs it would also allow you to share other data between view models.

如果您使用键值对字典,它还允许您在视图模型之间共享其他数据。

回答by Jeff

Singleton will definitely help. To implement, if I had a class named User:

单身人士肯定会有所帮助。为了实现,如果我有一个名为 User 的类:

    private static User mInstance;

    private User () //constructor
    {
    }

    public static User Instance
    {
        get
        {
            if (mInstance == null)
                mInstance = new User();
            return mInstance;
        }
    }