How to set communication / data transfer data between two ViewModels

I know that this question has already been asked repeatedly, and I have read many answers related to it. However, none of them complied with my requirements, and therefore I need advice.

The application that I am currently developing is as follows: http://screenshooter.net/100101493/smrkpog

This is a WPF MVVM application based on the MVVM Light Toolkit. The area with the grid is ListBox + Canvas . Elements (let them be called "Names") consist of ListBox + Canvas and each of them is dynamically created by the user. Each Neume element consists of "Elements" that appear as red shapes.

When the user double-clicks Neume, a new window opens. It is supposed to enable editing (translation, resizing, rotation) of the elements of which the selected Neume is made. What I would like to do is pass my SelectedNeume (with a list of items) stored in my MainViewModel to the ViewModel of my newly created window. I have some ideas on how to achieve this. :

  • Skip the new ViewModel completely and set MainViewModel as the DataContext new window,
  • Create the "MainViewModel" field in the new ViewModel and pass it there when a new window opens,
  • Use the Messaging / Mediator template provided by the MVVM Light Toolkit.

I am looking for a solution that is simple and neat. I would be very happy to use option 3., but I'm a relative newbie regarding WPF and don't know how to actually get started. In addition, I am afraid that there may be a problem that a new window opens when a double-click event occurs in the main ListBox, because I could not find a way to bind the command to the ListBoxItem element either in its style or DataTemplate (the event trigger / EventToCommand solution does not work for me).

This event:

  private void ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e) { var item = ((FrameworkElement)e.OriginalSource).DataContext as Neume; if (item != null) { var view2 = new EditWindow(); view2.Owner = this; view2.SetDataContext(); view2.ShowDialog(); } } 

Currently, the SetDataContext() method binds the DataContext according to parameter 1.

 public void SetDataContext() { if(this.Owner != null) DataContext = this.Owner.DataContext; } 

My question is : Which option would you recommend? Are there any problems with 1 or 2.? Possible memory leaks?

+6
source share
1 answer

Personally, I would go with option 3.

The messaging engine keeps your view modes separate from each other, and as soon as you work with one example, you will see that it is quite simple.

Personally, I like to add a class of message broker with static methods for each type of message I want to send, this helps me centralize the changes - but essentially you have send and receive. You can send what you want, and if something wants to receive it, they can.

MVVM Light is a great foundation for this.

Send:

 GalaSoft.MvvmLight.Messaging.Messenger.Send<LoginSuccessMessage>(new LoginSuccessMessage() { UserName = user }); 

Get in my target view the model constructor:

 this.MessengerInstance.Register<LoginSuccessMessage>(this, this.OnLoginSuccessMessage); 

Handler in the target view model:

  private async void OnLoginSuccessMessage(LoginSuccessMessage message) { this.CurrentUserName = message.UserName; this.MoveToState(ApplicationViewModelState.Active); await Task.Delay(5000); this.MoveToState(ApplicationViewModelState.Idle); } 

In this example, I am sending the user ID as a property in the message class:

 public class LoginSuccessMessage : MessageBase { private string _UserName; public string UserName { get { return this._UserName; } set { this._UserName = value; } } } 

Replace this property with what you want to assemble or a complex object.

+7
source

Source: https://habr.com/ru/post/973410/


All Articles