如何在两个或多个视图中共享单个Viewmodel?

时间:2014-02-07 07:25:42

标签: c# wpf mvvm command

我知道在MVVM中我们不应该在视图中使用viewModel,但我的应用程序需要它。所以我有一个视图和相应的ViewModel

说LinkView和LinkViewModel

LinkWindow构造函数中的

public LinkWindow(string path)
{
    InitializeComponent();
    LinkViewModel vm = new LinkViewModel(path);
    this.DataContext = vm;     
}

所以LinkWindow及其相应的LinkViewModel正在初始化。现在在LinkWindow中我有一个按钮会弹出一个窗口(As和必要时)但我需要相同的viewModel实例(vm)

该按钮实现了命令"LinkEmailCommand"

LinkEmailCommand = new Command(DoEmailCommand, false);

LinkViewModel

private void DoEmailCommand()
{
    var EmailWindow = new EmailWindow();
    EmailWindow.Show();
}

此EmailWindow不使用已初始化的LinkViewModel。我该怎么做?

编辑 - 解决方案:

那么解决办法是在构造函数中传递“this”

LinkViewModel

private void DoEmailCommand()
{
    var EmailWindow = new EmailWindow(this);
    EmailWindow.Show();
}

然后在LinkWindow中传递一个构造函数

中的viewModel对象
public LinkWindow(LinkViewModel vm)
        {
            InitializeComponent();
            Title = FilrUI.Properties.Resources.ShareFilrEmail;
            this.DataContext = vm;
        }

现在所有视图模型的单个实例都可以在两个视图中使用。

3 个答案:

答案 0 :(得分:2)

  

我知道在MVVM中我们不应该在视图中使用viewModel

你为什么这么认为? 这是一种非常常见的做法 - 有几种方法来表示相同的数据。

private void DoEmailCommand()
{
    // do not do this!
    var EmailWindow = new EmailWindow(); 
    EmailWindow.Show();
}

您不应该从视图模型中创建视图。这会破坏MVVM的一个好处 - 代码可测试性,并带来视图模型和视图之间的紧密耦合。考虑使用服务或事件聚合器来显示新视图。

  

我该怎么做?

显然,两个视图需要相同的视图模型实例。您可以做的最简单的事情是将视图模型实例传递给EmailWindow构造函数,或者通过属性为EmailWindow分配视图模型。

答案 1 :(得分:1)

EmailWindow中添加一个属性ViewModel。然后只需在命令处理程序中执行此操作:

private void DoEmailCommand()
{
    var EmailWindow = new EmailWindow();
    EmailWindow.ViewModel = vm;
    EmailWindow.Show();
}

当然,您还需要重构LinkWindow以将vm作为字段。像这样:

// Field for the viewmodel
private LinkViewModel vm;

public LinkWindow(string path)
{
    InitializeComponent();
    vm = new LinkViewModel(path);
    this.DataContext = vm;     
}

答案 2 :(得分:1)

在其他类中创建viewModel,然后将其传递给两个视图构造函数:)

public LinkWindow(string path, object viewModel)
{
    InitializeComponent();
    this.DataContext = viewModel;    
}

第二种观点中的方式相同。只需使用相同的viewModel对象实例