我正在构建我的第一个WPF和MVVM应用程序。我有3个视图(有3个对应的ViewModels)
1)MainWindow(窗口)
2)ViewClients(UserControl)
3)ViewModClient(UserControl)
在客户端ViewModel中,我有一个属性 SelectedClient ,用于跟踪视图中DataGrid上的选定客户端。在这个视图中,我还有一个与MainWindow ViewModel中定义的ICommand相关的按钮。 我用这个绑定来解决它:
Command="{Binding Path=DataContext.CreateViewsCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter={x:Type local:ViewModClient}
我使用CommandParameter告诉mainWindow ViewModel创建哪种视图并保持viewmodel与视图知识隔离。这非常有效。
现在出现问题:
在ModClient ViewModel中,我需要加载客户端的数据。那么如何在保持MVVM模式的同时将其与客户端视图中的 SelectedClient 联系起来呢? (我只能使用一个CommandParameter并且它已经使用过了)
答案 0 :(得分:1)
通常,这是通过使用消息传递来完成的。
所有MVVM框架都有一个消息传递总线,允许进行VM间通信,因此只需获得一个好的框架,任务就会变得如此简单(Simple MVVM Toolkit):
源VM:
SendMessage(MessageTokens.SomeToken, new NotificationEventArgs<string>
(MessageTokens.SomeToken, "MyMessage"));
接收VM:
RegisterToReceiveMessages<string>(MessageTokens.SomeToken, OnMessageReceived);
private void OnMessageReceived(object sender, NotificationEventArgs<string> e)
{
// Code to execute upon message reception.
}
答案 1 :(得分:1)
IEventAggregator
,它允许你创建可以订阅的Eventmanagers。如果您使用多个ViewModel订阅此特定EventAggegrator,则可以定义可以从已订阅此EventAggregator的所有ViewModel发布和接收的消息。
以下只是一个简短的实现,并显示,如果您使用像Caliburn.Micro这样的框架,ViewModel之间的通信会有多简单:
class ViewModel1 : PropertyChangedBase
{
private IEventAggregator _Event;
public ViewModel1(IEventAggregator events)
{
_Event = events;
_Events.Publish(new TestEvent(5));
}
}
class ViewModel2 : PropertyChangedBase, IHandle<TestEvent>
{
private IEventAggregator _Events;
public ViewModel2(IEventAggregator events)
{
_Events = events;
_Events.Subscribe(this);
}
public void Handle(TestEvent message)
{
// do something with the incoming message
}
}
class TestEvent
{
public int foo { get; set; }
public TestEvent(int someint)
{
foo = someint;
}
}
它应该是非常自我解释的。但是,如果您有任何疑问,请告诉我,我会详细介绍。