2010-09-14 115 views
13

可能重复:
How have you successfully implemented MessageBox.Show() functionality in MVVM?如何显示消息框在MVVM

我想显示消息框在我的MVVM WPF应用程序。 所以从哪里调用MessageBox.Show()。

+0

感谢它真的帮助我 – 2010-09-15 05:43:51

+1

这是严重downvoted和标记为重复,但它也是谷歌的'mvvm messagebox wpf'的结果... – Benjol 2013-04-30 09:24:37

+0

只是说... ..可能不是很漂亮或什么,但你可以简单地调用System.Windows.MessageBox.Show(params);来自任何班级。 – Para 2013-12-05 15:59:44

回答

6

我发现MVVM在程序员中调用了一条OCD(我从经验中知道)。这是好事。但是对于某些事情来说,这些努力并不值得,尤其是如果它引入了复杂性的整个顺序,只是询问用户“你确定你想要xxxx吗?”

我认为MessageBox.Show()可以从代码隐藏,但从来没有ViewModel调用。在对话框与XAML更好地结合之前,只需点击并且不会感觉不好。这实际上是WPF UI设计当前状态的一个灰色区域。

+2

我使用的命令,所以如果我将不得不显示消息框后按钮的可以执行和执行功能,我需要传递一些数据查看文件后面的代码,然后它会打破mvvm。 – 2010-09-15 04:30:07

13

在没有MVVM的Windows窗体或WPF中,您可以只说MessageBox.Show()就是这样!如果你可以在MVVM中做同样的事情,会不会很好?

下面是一个方法来做到这一点 - 它是尽可能接近MessageBox.Show()。

这是MVVM友好的MessageBox_Show()

public class MyViewModel: ViewModelBase 
{ 
    protected void AskTheQuestion() 
    { 
     MessageBox_Show(ProcessTheAnswer, "Are you sure you want to do this?", "Alert", System.Windows.MessageBoxButton.YesNo); 
    } 

    public void ProcessTheAnswer(MessageBoxResult result) 
    { 
     if (result == MessageBoxResult.Yes) 
     { 
      // Do something 
     } 
    } 
} 

田田!

这里是它如何工作的:

所有这一切MessageBox_Show实际上做的是触发一个事件,所以它是完全MVVM友好。 ViewModel对可能或不可能使用它的任何视图都一无所知,并且它并不单独执行Windows MessageBox的显示,因此它也可以安全地进行单元测试。

在视图中使用它,这将导致其实际显示一个MessageBox,你只要订阅事件并调用e.Show()事件处理程序,如下所示:

public partial class MyView : UserControl 
{ 
    public MyView() 
    { 
     InitializeComponent(); 

     this.DataContext = new MyViewModel(); 
     (this.DataContext as MyViewModel).MessageBoxRequest += new EventHandler<MvvmMessageBoxEventArgs>(MyView_MessageBoxRequest); 
    } 

    void MyView_MessageBoxRequest(object sender, MvvmMessageBoxEventArgs e) 
    { 
     e.Show(); 
    } 
} 

而且这就是您需要做的,以显示MVVM友好的Windows消息框。

下面的代码只需要在你的项目中实现一次,或者你可以把它放在一个可重用的共享库中。

添加到您的视图模型基类,所以它可以从任何视图模型被用于:

public class ViewModelBase : INotifyPropertyChanged 
{ 
    //... 

    public event EventHandler<MvvmMessageBoxEventArgs> MessageBoxRequest; 
    protected void MessageBox_Show(Action<MessageBoxResult> resultAction, string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.None, MessageBoxOptions options = MessageBoxOptions.None) 
    { 
     if (this.MessageBoxRequest != null) 
     { 
      this.MessageBoxRequest(this, new MvvmMessageBoxEventArgs(resultAction, messageBoxText, caption, button, icon, defaultResult, options)); 
     } 
    } 
} 

然后添加EventArgs类的事件处理程序:

public class MvvmMessageBoxEventArgs : EventArgs 
{ 
    public MvvmMessageBoxEventArgs(Action<MessageBoxResult> resultAction, string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.None, MessageBoxOptions options = MessageBoxOptions.None) 
    { 
     this.resultAction = resultAction; 
     this.messageBoxText = messageBoxText; 
     this.caption = caption; 
     this.button = button; 
     this.icon = icon; 
     this.defaultResult = defaultResult; 
     this.options = options; 
    } 

    Action<MessageBoxResult> resultAction; 
    string messageBoxText; 
    string caption; 
    MessageBoxButton button; 
    MessageBoxImage icon; 
    MessageBoxResult defaultResult; 
    MessageBoxOptions options; 

    public void Show(Window owner) 
    { 
     MessageBoxResult messageBoxResult = MessageBox.Show(owner, messageBoxText, caption, button, icon, defaultResult, options); 
     if (resultAction != null)resultAction(messageBoxResult); 
    } 

    public void Show() 
    { 
     MessageBoxResult messageBoxResult = MessageBox.Show(messageBoxText, caption, button, icon, defaultResult, options); 
     if (resultAction != null) resultAction(messageBoxResult); 
    } 
} 

单元测试很简单:

target.AskTheQuestion(); 
target.ProcessTheAnswer(System.Windows.MessageBoxResult.Yes); 

快乐编码!

+0

非常有用!谢谢 – Latrova 2016-04-05 12:34:03

+0

好的实现,但它使用事件,这将肯定会导致内存泄漏,特别是当你有很多的意见。 – 2016-09-16 09:33:40

+0

但是通过使用ViewModelBase中的System.Windows对MessageBoxResult的引用,MessageBoxOptions是不是击败了MVVM的目的? – 2017-01-04 09:41:47