How to receive DialogResult using mvvm-light Messenger

£可爱£侵袭症+ 提交于 2019-12-03 00:20:51

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.

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");
TomerBu

In order to achieve the above using DialogMessage as the title suggests, one may 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*/ }
}

receiver 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);
}

note the explicit call to the Callback method in the last line of the receiver.

msg.Callback(result);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!