我有以下关于 MVVM 灯的问题:是什么“驱动”了 UI?我看到我可以为每个视图显示一个 ViewModel;ViewLocator 处理所有 ViewModel(据我所知,用于缓存)。但是是什么在驱动 UI?
如果我在 ViewModel 中定义了一个显示“ShowDetail”的命令;我是否必须编写代码才能在 ViewModel 中显示此视图?
有这方面的例子吗?谢谢!
我有以下关于 MVVM 灯的问题:是什么“驱动”了 UI?我看到我可以为每个视图显示一个 ViewModel;ViewLocator 处理所有 ViewModel(据我所知,用于缓存)。但是是什么在驱动 UI?
如果我在 ViewModel 中定义了一个显示“ShowDetail”的命令;我是否必须编写代码才能在 ViewModel 中显示此视图?
有这方面的例子吗?谢谢!
MVVM 模式本身没有任何特定于视图之间导航的内容。虽然,在几个框架中有很多解决方案。最常见的解决方案是使用某种“编排”主视图的控制器,或者对子视图使用“主从”方法。
一些有趣的解决方案:
我创建了一个 T4 模板,它生成代码并显示如何导航到 uri 或对象,或关闭窗口 (wpf)。它适用于 mvvm light
在 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}" />
我想你可以看看 Cinch V2:
http://www.codeproject.com/KB/WPF/CinchV2_1.aspx
这似乎很有希望。但是我认为这些框架中的大多数都相当困难。
我使用一种简单的 MVVM 方法实现了一个解决方案,该方法具有某种监督控制器模式,用于处理视图和视图模型之间的通信。
我建议您阅读 MVVM 轻量级工具包中的消息系统。这似乎是我发现完成此任务的最简单方法。这是它如何工作的示例:
如果您有 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 个视图模型发送更改通知,例如 customerID 属性更改,并且立即有 4 个其他视图模型收到该更改,并且都开始自己加载更改。