【问题标题】:How to receive DialogResult using mvvm-light Messenger如何使用 mvvm-light Messenger 接收 DialogResult
【发布时间】:2011-06-22 13:16:40
【问题描述】:

我正在尝试使用 mvvm-light messenger 功能在我的视图中打开自定义确认密码对话框,由我的视图模型中的命令触发。

我想我了解Messenger.Default.RegisterMessenger.Default.Send 的用法。

但是如何在我的视图模型中恢复对话结果?

对我来说,发送似乎是一条单行道......

有人可以用一个小的 C#/WPF 代码示例帮助初学者吗?

感谢您的帮助

【问题讨论】:

    标签: wpf mvvm-light


    【解决方案1】:

    恕我直言,最好使用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&lt;MessageResult&gt; 进行子类化。即

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

    变得清晰了很多。

    并且非常重要取消注册收件人,否则您可能会造成内存泄漏。

    【讨论】:

    • +1:您的回答很有帮助!谢谢你的好解释。也不知道注销问题。不幸的是,我找不到任何好的和完整的 mvvm-light 文档,只有一些博客和示例代码。
    • 效果很好。一个小错误:发件人端应该是 'var msg = new ShowPasswordMessage(this, (r) =>'。也许您可以编辑它以供将来参考(我没有足够的权限)
    • @nabulke:Laurent 在galasoft.ch 的博客有一些很好的例子。他的 MIX 2010 视频也是启动 mvvm light 的必备品。帖子已编辑。
    • @AxelEckenberger 这是一个不错的答案,但有一个问题,如果有人想将 ViewModel 层放在单独的程序集中怎么办?因此,直接在 ViewModel 中使用 MessageBoxResult 需要对 System.Windows 的引用,而这并不是最好的,因为我们想放松对 UI 层的任何依赖。
    • 我的意思是,如果我们在这里接受直接在 ViewModel 层中使用 MessageBoxResult,那么有更简单的方法可以做到这一点,但对使用 DI 和 IoC 的任何未来更改保持开放。
    【解决方案2】:

    在注册方法中,您可以显示一个对话框并传递 YourViewModel 引用。

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

    您可以在代码中的某处抛出 Send() 消息并引用 YourViewModel,如下所示:

    Messenger.Default.Send(viewModel, "showDialog");
    

    【讨论】:

    • Messenger.Default.Send() 是一个异步函数,立即返回,不是吗?那么如何知道对话框何时关闭,可以查询结果呢?
    • 我可以使用回调函数或类似的东西吗?我有点困惑。
    • Send() 函数将触发弹出对话框的 lambda。由于它是模态对话框(ShowDialog 方法),它会阻塞工作流,直到它关闭。
    • 感谢您的回答阿塞尼。
    【解决方案3】:

    为了实现上述使用 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);
    

    【讨论】:

      猜你喜欢
      • 2016-02-07
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多