How do I interact between ViewModels?

I use MVVM Light and used a packaged messaging system to exchange data between view models, however I ran into some dilemma! Basically, when a user clicks on a customer record, the corresponding view is opened and an instance of CustomerViewModel is created with it. At this point, the CustomerViewModel requires that the selected customer identifier from the previous view model (ViewAllCustomersViewModel) so that it can retrieve the selected customer information that the view is bound to (still?). Therefore, initially, my thought also sent this identifier in a message from ViewAllCustomersViewModel (where the client is selected for viewing) to CustomerViewModel ... HOWEVER, CustomerViewModel is not created to be able to receive a message before loading the view (at that moment the message was already sent)!

So what would be the best way to solve this problem? So far, I have been considering a CustomerViewModel sending a request to the ViewAllCustomersViewModel after creating it (basically saying "I am ready to accept the message"), and then the ViewAllCustomersViewModel sends the identifier back to the CustomerViewModel ... but is this a necessary approach to solve this problem? It seems a little ugly to me!

Otherwise, I thought, is there any other way of communicating that can explain the problem I am having? But then, is not all the meaning of the messaging system ... to be able to communicate between viewing models? OR can I get an instance of the view model to start at startup? If so, how will this affect ViewModelLocator?

I hope that I have clearly stated the problem, I used the fictitious names of the models for the purpose of explanation ... and feel free to edit or suggest any additional information that you would like to add!

+7
c # wpf viewmodel mvvm mvvm-light
source share
5 answers

Have you tried to communicate through your model? I could not read your topic to the end, but this is how I communicate between ViewModels. Both view models have a session instance.

public ViewModel1(ISession session) { _session = session; } public ViewModel2(ISession session) { _session = session; } 

Thus, when testing your application in BDD (development based on behavior), you can test your application without presentation. Glue is a model.

As you can see in this picture, you can test your application without viewing. enter image description here

+5
source share

I believe that the standard way is to transmit via View. Depending on how you create your views, there may be a DependencyProperty for binding in XAML, a constructor parameter, or something else. Then View passes it the ViewModel (pushes it to the VM, and not vice versa: ViewModel does not need to know about View). This way you get a separate closed component (your view), and the external code is not aware of this internal implementation (which is the ViewModel).

In XAML, it could be something like

 <ListBox x:Name="customers" /> <CustomerView Customer="{Binding SelectedItem, ElementName=customers}" /> 

And then in the CustomerPropertyChanged handler, you push the value into the ViewModel.

+2
source share

Personally, I used MVVM-Light Messenger, but found that I have a way to many messages flying around, and I did not like the feeling of using a β€œmagic” messenger. What I did is indicated as an answer to the following link

The best way to transfer data to a new ViewModel when it starts .

Now I warn you, I answered my question and no one confirmed it as good or bad practice, however it works for my situation and eliminates the need for MVVM-Light Messenger. Since my program uses several threads in my implementation, I changed all the entries in the repository to dictionaries using CurrentThread.ManagedThreadId as the key.

+2
source share

I was faced with the same situation when two presentation models exchange each other. I used the Microsoft PRISM framework for publishing and subscribing.

In your case, CustomerViewModel is the parent view and ViewAllCustomersViewModel is a child.

  • Download the prism platform "Microsoft.Practices.Prism.PubSubEvents.dll" from https://www.nuget.org/packages/Prism.PubSubEvents/

  • Add a link to the prism to your project "Microsoft.Practices.Prism.PubSubEvents.dll"

  • Create your own custom class that is used for the communication modem.

    Notifications class: PubSubEvent {

    }

  • Create a singlehost instance of the IEventAggregator instance for your project and initialize it.

    closed private class SessionInfo {public IEventAggregator eventHanlder; private SessionInfo () {

      } private static SessionInfo _instance = null; public static SessionInfo Instance{ 

    will arrive {lock (lockObj) {if (_instance == null) {_instance = new SessionInfo (); _instance.eventHanlder = new EventAggregator (); }} return _instance; }}}

  • Go to handling the events of the Popover buttons (ViewAllCustomersViwModel) and below in it. Now it is published.

In ViewAllCustomersViwModel.cs:

  public void OnSelectedItem(Item item) { SessionInfo.Instance.eventHanlder.GetEvent<Notification>().Publish(item.id); } 
  1. This event aggregator should subscribe where necessary. Therefore, add the code below to the parent view model (CustomerViewModel).

CustomerViewModel.cs

  public class CustomerViewModel { public CustomerViewModel() { SessionInfo.Instance.eventHanlder.GetEvent<Notifications>().Subscribe(OnReceivedNotification); } //Handling the notification public void OnReceivedNotification(string itemId) { Debug.WriteLine("Item Id is :" + itemId); } } 

For more information:

https://sites.google.com/site/greateindiaclub/mobil-apps/windows8/communicationbetweenviewmodelsinwindows8mvvmpattern

+2
source share

So far, I reviewed the CustomerViewModel by sending a request to the ViewAllCustomersViewModel as soon as it was created (basically saying: "I am ready to accept the message"), and then the ViewAllCustomersViewModel sends the identifier back to the CustomerViewModel ...

I would continue this idea. It preserves the views, models of ViewModels and Models separately and the unknowing of others, unlike other answers. This is not to say that the other answers are incorrect or even bad, your option can be defined as one or any of: personal preferences, team agreement, the long-term goal of MVVM to replace components / modules and the complexity / simplicity of coding.

A side effect to your idea, which I quoted above, which I prefer, is that you can request at any time, as you have already installed it. Therefore, if you change when it is very easy to execute this request, or if you need to request updates, you use the same communication architecture.

Finally, I prefer it because if you change your models or views or viewing modes, you keep the same basic concept of transferring information between components.

+1
source share

All Articles