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

时间:2012-07-24 10:28:51

标签: c# mvvm mvvm-light

我最近开始使用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<LaunchShowReservoirMessage>(this,OnLaunchShowReservoir);
    }
    
    public void OnLaunchShowReservoir(LaunchShowReservoirMessage msg) {
        var showReservoir = new ReservoirViewerView();
        showReservoir.Show(); 
    }
    
  5. 我需要的是新的ViewModel(ReservoirViewerViewModel)可以通过消息以某种方式获取传递的对象,以便我可以在子窗口上显示该对象的详细信息。

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

2 个答案:

答案 0 :(得分:0)

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

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

在ReservoirViewerViewModel中:

private void RegisterMessages() 
{
    Messenger.Default.Register<LaunchShowReservoirMessage>(this, ReservoirReceived);
}

private void ReservoirReceived(LaunchShowReservoirMessage msg) {
    this.LocalReservoir = msg.Reservoir;
}

public Reservoir LocalReservoir { get... set... } ...

答案 1 :(得分:0)

  

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

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

CodeBehind

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

Xaml视图

<Window x:Class="Garmin.Cartography.AdminBucketTools.ChildWindowView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    DataContext="{Binding Path=ReservoirViewerViewModel, Source={StaticResource Locator}}">
    <!--Use the non-static property in your ViewModelLocator-->

    <Grid />
</Window>

Xaml资源

<DataTemplate DataType="{x:Type viewmodels:ReservoirViewerViewModel}">
    <views:ReservoirViewerView/>
</DataTemplate>
  

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

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

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

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

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

然后:

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