【问题标题】:MVVM design: Blocking MessageBox in ViewModelMVVM 设计:在 ViewModel 中阻塞 MessageBox
【发布时间】:2016-05-06 11:23:00
【问题描述】:

本题涉及基于 PRISM 5.0 和 MVVM 模式的 WPF 应用程序。

有时当用户做出可能会产生不良或负面后果的决定时,通常会询问用户是否真的想继续下去。

例如: 一种常见的方法是用消息框询问用户,如果他真的想删除数据,删除后无法恢复。

问题是: 如果我在 ViewModel 中调用 MessageBox,ViewModel 从外部变为 untestable

//BAD!
public class ViewModel
{
    public Boolean Delete()
    {
        //Blocking and therefore untestable in automatic UnitTests
        MsgBoxResult result = MsgBox.Show("Do you really want to delete?"); 

        if (result == yes) {//Do stuff that deletes data here;}

    }
}

一种可能性是,以不同的私有方法提出问题,该方法调用公共方法

//BETTER, BUT OK?
public class ViewModel
{
    private void OnDeleteAction
    {
        MsgBoxResult result = MsgBox.Show("Do you really want to delete?"); 
        if (result == yes) {Delete();}
    }

    public Boolean Delete()
    {
        //Testable from the outside again, because no blocking question

        //Do stuff that deletes data here
    }

我的问题:这是在 ViewModel 中询问用户的好方法还是有更优雅的方法?你能给我一个提示或链接,什么是 PRISM 5.0 最好的?

我知道,经验法则是,不要在 ViewModel 中使用任何 UI 元素,但我认为在继续之前,除了阻塞 MessageBox 或其他东西之外别无选择。

感谢您的任何提示!

【问题讨论】:

  • 据我了解,不应在视图模型中编写任何与视图相关的代码,在视图端编写与逻辑相关的代码。因此,您可以在视图代码中打开消息框,并根据您在视图模型类中调用删除方法的用户选择。
  • public interface MuhMessageBox { bool AreYouCrazy(string message); }

标签: c# wpf mvvm prism blocking


【解决方案1】:

据我所知,有两种选择可以减少 View 和 ViewModel 之间的耦合:使用交互服务和触发交互请求。两者都解释得很好here;你可能想看看。

一般的想法是,您将异步交互的完成方式抽象化,并使用更类似于基于事件的逻辑的方式工作,同时允许 ViewModel 表达它希望与用户交互作为操作的一部分;最终结果是您可以记录此交互并对其进行单元测试。

【讨论】:

  • 再次感谢您,塞巴斯蒂安。您的提示很有帮助,但在这种情况下,我接受 R.Richards 的回答作为最好的帮助,因为他的代码示例很棒。在接受的答案下查看我的评论。
【解决方案2】:

Prism Interactivity 是这里的必经之路。这允许您执行确认、通知和创建与 MVVM 模式配合良好的自定义对话框。我在 Prism 应用程序中成功使用了它们。

以下是 GitHub 上 Prism 存储库中一些代码的链接:

Notification Request

Confirmation Request

Custom Content

Custom Request

【讨论】:

  • Sebastian Schulz 和 R.Richards 的两个答案都有很大帮助,但我接受这个答案胜过其他答案,因为 R.Richards 提供的代码示例对我帮助最大。如果您不知道从哪里开始,请查看示例,当涉及到 WPF、MVVM 和交互性时,它非常棒并且让很多事情变得清晰。非常感谢。
  • @Flynn1179 添加了更新的链接。
猜你喜欢
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多