MVVM设计:在ViewModel中阻止MessageBox

时间:2016-05-06 11:23:01

标签: c# wpf mvvm prism blocking

此问题涉及基于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或其他东西。

谢谢你的任何提示!

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

Prism Interactivity是去这里的方式。这允许您执行确认,通知,并创建与MVVM模式良好协作的自定义对话框。我在Prism应用程序中成功使用它们。

以下是GitHub上Prism repo中一些代码的链接:

Notification Request

Confirmation Request

Custom Content

Custom Request