How to get DialogResult using mvvm-light Messenger

I am trying to use the mvvm-light messenger function to open a custom password confirmation dialog in my view, invoked by a command in my view model.

I think I understand the use of Messenger.Default.Register and Messenger.Default.Send .

But how do I return the results of a dialog to my view model?

It seems to me that the dispatch is a one-way street ...

Can someone help a newbie with a little C # / WPF code example?

Thanks for any help

+8
wpf mvvm-light
source share
3 answers

IMHO, it is better to use NotificationMessageAction<T> , since it is cut for this task.

On the sender side:

 var msg = new NotificationMessageAction<MessageBoxResult>(this, "GetPassword", (r) => { if (r == MessageBoxResult.OK) { // do stuff } }); Messenger.Default.Send(msg); 

And on the receiver side:

 Messenger.Default.Register<NotificationMessageAction<MessageBoxResult>>(this, (m) => { if (m.Notification == "GetPassword") { var dlg = new PasswordDialog(); var result = dlg.ShowDialog(); m.Execute(result); } }); 

I believe this approach is cleaner since it does not create an unnecessary dependency on View to ViewModel (although this path is not so bad). For better readability, consider subclassing for NodificationMessageAction<MessageResult> . I.e.

 public class ShowPasswordMessage : NotificationMessageAction<MessageBoxResult> { public ShowPasswordMessage(object Sender, Action<MessageBoxResult> callback) : base(sender, "GetPassword", callback) { } } 

Then sender

 var msg = new ShowPasswordMessage(this, (r) => { if (r == MessageBoxResult.OK) { // do stuff } }); Messenger.Default.Send(msg); 

and receiver side

 Messenger.Default.Register<ShowPasswordMessage>(this, (m) => { var dlg = new PasswordDialog(); var result = dlg.ShowDialog(); m.Execute(result); }); 

It becomes much clearer.

And verry important, unregister the recipient, as otherwise you could create a memory leak.

+15
source share

In the Register method, you can display a dialog and pass the link YourViewModel.

  Messenger.Default.Register<YourViewModel>(this, "showDialog", viewModel=> { var dlg = new Dialog(); viewModel.Result = dlg.ShowDialog(); }); 

somewhere in your code you can send a Send () message with a link to YourViewModel as follows:

 Messenger.Default.Send(viewModel, "showDialog"); 
+1
source share

To achieve the above using DialogMessage, as the name suggests, you can use the following:

sender side:

 void SendMessage(String msgText) { DialogMessage messege = new DialogMessage(msgText, res => { callback(res); }) //set more dialog properties using the Initializer { Button = MessageBoxButton.OKCancel, Caption = "" }; Messenger.Default.Send(messege, "mb1"); } public void callback(MessageBoxResult res) { if (res == MessageBoxResult.OK) { /*do something*/ } } 

recipient side:

 void Rec() { Messenger.Default.Register<DialogMessage>( this, "mb1", msg => ShowDialog(msg)); Unloaded += Unreg; } void ShowDialog(DialogMessage msg) { var result = MessageBox.Show( msg.Content, msg.Caption, msg.Button); msg.Callback(result); } 

Notice the call to the explicit callback method on the last line of the recipient.

 msg.Callback(result); 
0
source share

All Articles