C# MVVM设计:在ViewModel中阻塞MessageBox

C# MVVM设计:在ViewModel中阻塞MessageBox,c#,wpf,mvvm,prism,blocking,C#,Wpf,Mvvm,Prism,Blocking,这个问题涉及一个基于PRISM 5.0和MVVM模式的WPF应用程序 有时,当用户做出决策时,可能会产生不想要的或负面的后果,通常会问用户是否真的想继续下去 例如: 一种常见的方法是,用messagebox询问用户,如果他真的想删除数据,删除后无法恢复 问题是: 如果我在ViewModel内部调用MessageBox,则ViewModel从外部变得不稳定 //BAD! public class ViewModel { public Boolean Delete() {

这个问题涉及一个基于PRISM 5.0和MVVM模式的WPF应用程序

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

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

问题是: 如果我在ViewModel内部调用MessageBox,则ViewModel从外部变得不稳定

//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中的用户?你能给我一个提示或链接,什么是棱镜5.0最好的

我知道,经验法则是,不要在ViewModel中使用任何UI元素,但我认为在继续之前,除了阻止MessageBox或其他东西之外,没有其他方法可以阻止流程


谢谢你的任何提示

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


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

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


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

Prism交互是实现此目的的方法。这允许您进行确认、通知,并创建与MVVM模式配合良好的自定义对话框。我在Prism应用程序中成功地使用了它们

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


棱镜互动是这里的发展方向。这允许您进行确认、通知,并创建与MVVM模式配合良好的自定义对话框。我在Prism应用程序中成功地使用了它们

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


根据我的理解,不应该在视图模型中编写任何视图相关代码,而在视图端编写任何逻辑相关代码。因此,您可以在view code behind中打开消息框,并基于您在view model类中调用delete方法的用户选择。
public interface MuhMessageBox{bool AreyouCray(string message);}
根据我的理解,不应在view model中编写任何视图相关代码,在view side中编写逻辑相关代码。因此,您可以在view code behind中打开消息框,并基于您在view model类中调用delete方法的用户选择。
public interface MuhMessageBox{bool AreyouCray(string message);}
Sebastian Schulz和R.Richards的两个答案都很有帮助,但我接受这个答案,因为R.Richards提供的代码示例对我帮助最大。如果你不知道从哪里开始,看看这个例子,它是非常棒的,它清楚地说明了很多事情,涉及到WPF、MVVM和交互性。非常感谢。@Flynn1179添加了更新的链接。塞巴斯蒂安·舒尔茨和R.理查兹的两个答案对我帮助很大,但我接受这个答案,因为R.理查兹提供的代码示例对我帮助最大。如果你不知道从哪里开始,看看这个例子,它是非常棒的,它清楚地说明了很多事情,涉及到WPF、MVVM和交互性。非常感谢。@Flynn1179已添加更新链接。再次感谢您,塞巴斯蒂安。您的提示是一个很大的帮助,但在本例中,我接受R.Richards的回答作为最好的帮助,因为他的代码示例很棒。请看我在接受答案下的评论。再次感谢你,塞巴斯蒂安。您的提示是一个很大的帮助,但在本例中,我接受R.Richards的回答作为最好的帮助,因为他的代码示例很棒。请参阅我在已接受答案下的评论。