MVVM指示灯:将对象从视图传递到viewmodel

我最近开始使用MVVM灯使用WPF,我有以下(简单场景)。

  1. MainWindow包含元素列表框。

  2. 选择一个并单击该按钮后,我将触发一个命令:

    ReservoirViewerCommand.Execute(null); 
  3. 在viewmodel类上,我实例化该命令并发送带有所选对象的消息:

     ReservoirViewerCommand = new RelayCommand(OpenReservoir); private void OpenReservoir() { Messenger.Default.Send(new LaunchShowReservoirMessage(){Reservoir=SelectedReservoir}); } 

    哪里:

     class LaunchShowReservoirMessage:MessageBase { public Reservoir Reservoir { get; set; } } 
  4. 主视图注册消息并打开一个新的子窗口:

     private void RegisterMessages() { Messenger.Default.Register(this,OnLaunchShowReservoir); } public void OnLaunchShowReservoir(LaunchShowReservoirMessage msg) { var showReservoir = new ReservoirViewerView(); showReservoir.Show(); } 

我需要的是新的ViewModel(ReservoirViewerViewModel)可以通过消息以某种方式获取传递的对象,以便我可以在子窗口上显示该对象的详细信息。

我做了一些逐步调试,似乎永远无法访问ViewModel构造函数。

“我做了一些逐步调试,似乎永远无法访问ViewModel构造函数。”

确保使用以下方法之一将视图绑定到视图模型:

CodeBehind中

 var showReservoir = new ReservoirViewerView(); showReservoir.DataContext = ViewModelLocator.ReservoirViewerViewModel; //static property //OR showReservoir.DataContext = new ReservoirViewerViewModel(); showReservoir.Show(); 

Xaml视图中

     

Xaml Resources中

    

“我需要的是新的ViewModel(ReservoirViewerViewModel)可以通过消息以某种方式获取传递的对象,以便我可以在子窗口上显示该对象的详细信息。”

只需在您的ReservoirViewerViewModel类中注册相同的消息:

 Messenger.Default.Register(this, (msg) => { var reservoir = msg.Reservoir; }); 

仅供参考,如果从GenericMessage <[content type]>而不是MessageBase派生您的消息类,则可以使用GenericMessage类的已定义的Content属性。 例如:

 public class LaunchShowReservoirMessage: GenericMessage { public LaunchShowReservoirMessage(Reservoir content) : base(content) { } } 

然后:

 Messenger.Default.Register(this, (msg) => { var reservoir = msg.Content; }); 

我不是MVVM专家,但是当我想要导航到新视图以在点击ListBox项目后显示某些内容时,我会在我要在此新视图中显示的对象中发送一条新消息,然后我导航到。 我写这篇文章是因为我认为你的方法有点错综复杂,但我是一名Windows Phone应用程序开发人员,所以请相应地发表评论。

无论如何,消息的第一个function是允许通过视图模型进行通信,所以在我看来你应该在ReservoirViewerViewModel中注册消息,这里使用msg.Reservoir获取Reservoir“附件”。

在ReservoirViewerViewModel中:

 private void RegisterMessages() { Messenger.Default.Register(this, ReservoirReceived); } private void ReservoirReceived(LaunchShowReservoirMessage msg) { this.LocalReservoir = msg.Reservoir; } public Reservoir LocalReservoir { get... set... } ...