从现有视图模型访问视图模型的正确方法

从现有视图模型访问视图模型的正确方法

问题描述:

我对MVVM有点新鲜。我不确定最好的办法是做我想做的事情。从现有视图模型访问视图模型的正确方法

下面是这种情况:

我有一个虚拟机是要显示的另一个窗口。我可以拨打myNewWindowView.Show(),但首先我需要在我的新窗口的虚拟机中设置一些数据。

我是否应该将myNewWindowViewNewWindowViewModel都暴露给调用ViewModel?

下面是一个例子:

class MainVM 
{ 
    public void FindCustomer(string nameParial) 
    { 
     List<Customer> customers = ServiceCall.GetCustomers(nameParital); 
     // This is the part I am not sure how to do. I am not sure if this 
     // View Model should have a reference to a different view model and 
     // the view too. 
     myNewWindowViewModel.CustomerList = customers; 
     myNewWindowView.Show(); 
    } 
} 

我将保持视图模型从任何视图分开。我倾向于将它们看作层,但它们只能在一个方向上互换。

因此,一个foo类型的模型可以将任何视图模型放在它的顶层,并且它从不期望或关心视图模型类型。

视图模型只能用于一种模型,但它不关心或期待什么类型的视图将使用它。

视图将针对特定类型的视图模型。

你看起来有什么是一个viewmodel关心什么意见在做什么,这对我来说似乎是错误的。

如果是我,我会得到MainVM显示新窗口的视图,让MainVM为新窗口传递适当的视图模型。

这是代码,我会把观点背后的主视图模型

class MainWindow : Window 
{ 
    public MainWindow() 
    { 
      Initialize(); 
      DataContext = new MainVM(); 
    } 

    public void FindCustomerClick(object sender, RoutedEventArgs args) 
    { 
      CustomerListView clv = new CustomerListView(); 
      clv.DataContext = (DataContext as MainVM).FindCustomer(search.Text); 
      clv.Show(); 
    } 
} 

正如你所看到的,视图模型具有接受一个字符串,并返回一个CustomerListViewModel,然后将其应用到的方法CustomerListView的DataContext。

+0

听起来不错,但也听起来很模糊。你能告诉我一个你如何做我的例子的例子吗? (即有一个窗口打开另一个窗口,其间传递了一些数据。) – Vaccano 2010-10-31 19:42:14

+0

我会尝试。我可能需要稍后修复它,因为我是通过手机完成此操作:) – 2010-10-31 21:33:54

+0

除了将我的CustomerListView.DataContext设置为我的CustomerListViewModel外,这看起来不错。如果我设置为“FindCustomer”的结果,那么我将失去该视图的MVVM设置。 – Vaccano 2010-11-01 02:56:22

请勿在视图模型中引用视图。有视图创建视图和视图模型创建视图模型。

一个简单的方法来完成这种关注的分离与事件。快速和肮脏的方式做到这一点是建立在你的父视图模型ChildViewModel属性,然后在视图处理PropertyChanged,如:

ParentViewModel vm = (ParentViewModel)DataContext; 
vm.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) 
{ 
    if (e.PropertyName == "ChildViewModel") 
    { 
     MyChildWindow w = new MyChildWindow(); 
     w.Show(vm.ChildViewModel); 
    } 
}; 

现在每个父视图模型改变ChildViewModel财产时,父视图将打开一个新的子视图。

一个不太快,不太脏的,方法是创建一个CreateViewEventHandler委托和CreateViewEventArgs类,使事件处理程序,以及一个受保护的OnCreateView方法,您的基本视图模型类的部分(假设你有一个)。这使得视图模型可以更加明确地说明何时应该创建子窗口。

请注意,如果父视图模型知道子视图模型何时关闭很重要,则子视图模型可以公开父视图可以订阅的事件(或者再次使用属性和PropertyChanged事件)。

请注意,在这两种情况下,您都可以编写单元测试,验证视图模型是否打开窗口(即引发事件),而不涉及视图。

我自己并没有使用过任何MVVM框架,但是我看过的那些框架都有消息传递工具,它们被设计用来促进这种事情。