Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive DialogResult using mvvm-light Messenger

Tags:

wpf

mvvm-light

I'm trying to use the mvvm-light messenger capability to open a custom confirm password dialog in my view, triggered by a command in my viewmodel.

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

But how do I get the dialog results back in my viewmodel?

To me the sending seems to be a one way street...

Could someone help a beginner with a small C#/WPF code sample?

Thanks for any help

like image 297
nabulke Avatar asked Jun 22 '11 13:06

nabulke


2 Answers

IMHO it is better to use the NotificationMessageAction<T> as it is cut out 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 that this approach is cleaner as it does not create an unnecessary dependency from the View to the ViewModel (although this way round is not so bad). For better readability consider sub-classing the NodificationMessageAction<MessageResult>. I.e.

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

    }
}

Then the 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);
});

becomes a lot clearer.

And verry important unregister the recipient as else you might create a memory leak.

like image 118
AxelEckenberger Avatar answered Dec 07 '22 03:12

AxelEckenberger


In Register method you can show a dialog and pass the YourViewModel reference.

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

somewhere in your code you can throw Send() message with a reference to YourViewModel like this:

Messenger.Default.Send(viewModel, "showDialog");
like image 40
Arseny Avatar answered Dec 07 '22 04:12

Arseny