I \'ve recently started working with WPF using MVVM light and I have the following (simple scenario).
MainWindow contains a listbox of elements.
I'm not a MVVM expert but when I want to navigate to a new view to show something after clicking on ListBox Item I send a new message within the object that I want to show in this new view, and then I navigate to. I'm writing this because I'm thinking that Your approach is a little bit intricate, however I'm a Windows Phone app developer so take this comment accordingly.
Anyway, the first function of messages is to allow communication through viewmodels, so in my opinion you should register the message also in the ReservoirViewerViewModel and here get the Reservoir "attachment" using msg.Reservoir.
In ReservoirViewerViewModel:
private void RegisterMessages()
{
Messenger.Default.Register<LaunchShowReservoirMessage>(this, ReservoirReceived);
}
private void ReservoirReceived(LaunchShowReservoirMessage msg) {
this.LocalReservoir = msg.Reservoir;
}
public Reservoir LocalReservoir { get... set... } ...
"I did some step-by-step debugging and the ViewModel constructor seems never to be reached."
Make sure that you are actually binding your view to your view model using one of the following:
In CodeBehind
var showReservoir = new ReservoirViewerView();
showReservoir.DataContext = ViewModelLocator.ReservoirViewerViewModel; //static property
//OR showReservoir.DataContext = new ReservoirViewerViewModel();
showReservoir.Show();
In Xaml View
<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>
In Xaml Resources
<DataTemplate DataType="{x:Type viewmodels:ReservoirViewerViewModel}">
<views:ReservoirViewerView/>
</DataTemplate>
"What I need is that the new ViewModel (ReservoirViewerViewModel) can somehow get hold of the passed object through the message so that I can then display the details of this object on the child window."
Simply register for the same message in your ReservoirViewerViewModel class:
Messenger.Default.Register<LaunchShowReservoirMessage>(this, (msg) =>
{
var reservoir = msg.Reservoir;
});
FYI, if you derive your message class from GenericMessage<[content type]> instead of MessageBase, then you can use the already-defined Content property of the GenericMessage class. For example:
public class LaunchShowReservoirMessage: GenericMessage<Reservoir>
{
public LaunchShowReservoirMessage(Reservoir content) : base(content) { }
}
And then:
Messenger.Default.Register<LaunchShowReservoirMessage>(this, (msg) =>
{
var reservoir = msg.Content;
});