Как получить DialogResult с помощью mvvm-light Messenger - PullRequest
8 голосов
/ 22 июня 2011

Я пытаюсь использовать функцию mvvm-light messenger , чтобы открыть диалоговое окно подтверждения пароля в моем представлении, вызванное командой в моей модели представления.

Мне кажется, я понимаю использование Messenger.Default.Register и Messenger.Default.Send.

Но как мне вернуть результаты диалога в моей модели представления?

Мне кажется, что отправка - это улица с односторонним движением ...

Может ли кто-нибудь помочь новичку с небольшим примером кода C # / WPF?

Спасибо за любую помощь

Ответы [ 3 ]

15 голосов
/ 22 июня 2011

ИМХО лучше использовать NotificationMessageAction<T>, так как он вырезан для этой задачи.

На стороне отправителя:

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

Messenger.Default.Send(msg);

И на стороне получателя:

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

Я считаю, что этот подход более чистый, поскольку он не создает ненужную зависимостьот View до ViewModel (хотя этот путь не так уж и плох).Для лучшей читаемости рассмотрим подкласс NodificationMessageAction<MessageResult>.Т.е.

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

    }
}

Тогда отправитель

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

Messenger.Default.Send(msg);

и сторона получателя

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

становятся намного понятнее.

И verryважно отмените регистрацию получателя, иначе вы можете создать утечку памяти.

1 голос
/ 22 июня 2011

В методе Register вы можете показать диалоговое окно и передать ссылку YourViewModel.

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

где-то в вашем коде вы можете отправить сообщение Send () со ссылкой на YourViewModel, например:

Messenger.Default.Send(viewModel, "showDialog");
0 голосов
/ 10 декабря 2013

Для достижения вышеизложенного, используя DialogMessage, как следует из названия, можно использовать следующее:

сторона отправителя:

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*/ }
}

сторона получателя:

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

обратите внимание на явный вызов метода Callback в последней строке получателя.

msg.Callback(result);
...