从现有视图模型访问视图模型的正确方法
我对MVVM有点新鲜。我不确定最好的办法是做我想做的事情。从现有视图模型访问视图模型的正确方法
下面是这种情况:
我有一个虚拟机是要显示的另一个窗口。我可以拨打myNewWindowView.Show()
,但首先我需要在我的新窗口的虚拟机中设置一些数据。
我是否应该将myNewWindowView
和NewWindowViewModel
都暴露给调用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。
请勿在视图模型中引用视图。有视图创建视图和视图模型创建视图模型。
一个简单的方法来完成这种关注的分离与事件。快速和肮脏的方式做到这一点是建立在你的父视图模型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框架,但是我看过的那些框架都有消息传递工具,它们被设计用来促进这种事情。
听起来不错,但也听起来很模糊。你能告诉我一个你如何做我的例子的例子吗? (即有一个窗口打开另一个窗口,其间传递了一些数据。) – Vaccano 2010-10-31 19:42:14
我会尝试。我可能需要稍后修复它,因为我是通过手机完成此操作:) – 2010-10-31 21:33:54
除了将我的CustomerListView.DataContext设置为我的CustomerListViewModel外,这看起来不错。如果我设置为“FindCustomer”的结果,那么我将失去该视图的MVVM设置。 – Vaccano 2010-11-01 02:56:22