我有关于MVVM灯的以下问题:什么“驱动”UI?我看到我可以在每个View中显示一个ViewModel; ViewLocator处理所有ViewModel(根据我的理解用于缓存)。但是什么推动了用户界面?
如果我在ViewModel中定义了一个名为“ShowDetail”的Command;我是否必须编写在ViewModel中显示此View的代码?
有这方面的例子吗?谢谢!
答案 0 :(得分:5)
MVVM模式本身没有任何特定于视图之间导航的内容。虽然,在几个框架中有许多解决方案。 最常见的解决方案是使用某种控制器“编排”主视图,或使用“主 - 细节”方法进行子视图。
一些有趣的解决方案:
答案 1 :(得分:1)
在MVVM中,“驱动”视图的是数据绑定。您可以通过将View的DataContext设置为指向视图模型,将View连接到ViewModel。
简单示例(使用MVVM Light):
MyViewModel.cs
public class MyViewModel : ViewModelBase
{
(...)
private string _myProperty;
public string MyProperty {
get { return _myProperty; }
set {
_myProperty = value;
RaisePropertyChanged("MyProperty");
}
}
}
MyView.xaml.cs
void MyView() {
DataContext = new MyViewModel();
}
MyView.xaml
<TextBlock Text="{Binding MyProperty}" />
答案 2 :(得分:1)
我创建了一个T4模板,用于生成代码并显示如何导航到uri或对象,或关闭窗口(wpf)。它适用于mvvm light
答案 3 :(得分:0)
我想你可以查看Cinch V2:
http://www.codeproject.com/KB/WPF/CinchV2_1.aspx
这似乎很有希望。但是我认为大多数这些框架都相当困难。我使用一种简单的MVVM方法实现了一个解决方案,它采用某种监督控制器模式来处理视图和视图模型之间的通信。
答案 4 :(得分:0)
我建议你在MVVM light工具包中阅读Messaging系统。这似乎是我发现实现这一目标的最简单方法。以下是其工作原理的示例:
如果您有2个视图模型 - 1个用于搜索客户,另一个用于显示有关所选客户的详细信息:
在第一个视图模型中,您有一个如下属性:
public string CustomerID
{
get
{
return _customerid;
}
set
{
if (_efolderid == value)
{
return;
}
var oldValue = _customerid;
_customerid = value;
// Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
RaisePropertyChanged("CustomerID", oldValue, value, true);
}
}
然后,在第二个视图模型中,注册以在此值从另一个值更改时接收消息,例如:
void registerForMessages()
{
Messenger.Default.Register<PropertyChangedMessage<string>>(this,
(pcm) =>
{
if (pcm.PropertyName == "CustomerID")
{
customerID = pcm.NewValue;
AddWorkplanCommand.RaiseCanExecuteChanged();
loadCustomerDetails();
}
});
}
确保在第二个视图模型的构造函数中调用registerForMessages()函数。另一个有用的方法是在应用程序中有4个或更多ViewModel时创建一个排序映射。我发现很容易在解决方案中的快速文本文件中构建一个,以跟踪所有消息以及它们要完成的内容,以及注册哪些其他视图模型来接收它们。
关于这个的一个非常好的事情是你有1个viewmodel发送更改通知,例如更改了customerID属性,并且立即有4个其他viewmodel接收到该更改并且所有开始加载更改本身。