manro
manro

Reputation: 43

Pass an object from VM to VM within a View

I spent much time exploring the options to share objects between the VM and I came to a successful solution, but that is not exactly the most elegant:

Let's say I want to send from VM1 the _testObject object of class TestClass that is displayed in V1, which DataContext is obviously VM1 to VM2 and display it in the view V2.

public class VM1: ViewModelBase
{
   ...

   public VM1 ()
   {
      ...

      Messenger.Default.Register <bool> (this, "isLoaded" t => Messenger.Default.Send<TestClass> (_testObject "myObject"));
    }

    ...
}

    public partial class V2: PhoneApplicationPage
    {
       public V2 ()
       {
          InitializeComponent ();
       }

       protected override void OnNavigatedTo (System.Windows.Navigation.NavigationEventArgs e)
       {
          Messenger.Default.Register <TestClass> (this.DataContext "myObject", mo => (this.DataContext and VM2). PropertyInVM2 = mo);
          Messenger.Default.Send <bool> (true, "isLoaded");
          base.OnNavigatedTo (e);
       }

       protected override void OnNavigatedFrom (System.Windows.Navigation.NavigationEventArgs e)
       {
          Messenger.Default.Unregister <TestClass> (this.DataContext "myObject");
          base.OnNavigatedFrom (e);
       }
    }

So if app is navigated to V2, it wait until the page is created, then sends the message "isLoaded" which is captured in VM1, and then VM1 send a message with the objects you need to VM2.

No, I do not like it this way, and I do not want a in code bihnd. Can anyone advise me more elegant way?

Upvotes: 0

Views: 216

Answers (2)

Chris Koenig
Chris Koenig

Reputation: 2748

[caveat: Since you tagged this question with MVVM-Light, and mention Messenger in your post, I presume that you're using the MVVM Light framework.]

What I've done in the past is to either have the VML create both VMs explicitly when the app starts up, or have the VML register for the events and pass them from VM to VM as necessary.

  • In the first case, VM2 would register to hear the message, and VM1 would send it. Since the VML instantiated both VMs, both are alive when the message is sent and everything works as expected.
  • In the second case, the VML is always alive, and can lazy-load VM2 as necessary when VM1 sends the message.

In both cases, V1 and V2 are not involved in the message passing at all, which is good.

A third option, depending on your application complexity/needs/architecture/etc is to share VM1 between V1 and V2. Then you don'thave to pass any data anywhere :) This approach works OK for small applications, but if your app is complex you can easily get into trouble.

Either approach has it's pros and cons, but that's the ways I understand you can do this with MVVM Light. FWIW - EventAggregator is part of Prism, not part of MVVM Light, so using EventAggregator means taking on additional dependencies from the Prism framework which you may or may not want to do. Since the EventAggregator and Messenger perform similar functions, you could potentially combine them together, but I've not tried this.

Upvotes: 1

123 456 789 0
123 456 789 0

Reputation: 10865

What I would suggest is to use EventAggregator and subscribe/publish through your interface the Message from VM to another VM.

It's more elegant to use a IoC and let the communication of the VMS be handled by it.

Upvotes: 0

Related Questions