可能重复:
How have you successfully implemented MessageBox.Show() functionality in MVVM?
我想在我的MVVM WPF应用程序中显示消息框。 所以从哪里调用MessageBox.Show()。
答案 0 :(得分:15)
在Windows窗体或没有MVVM的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,因此它也可以安全地进行单元测试。
要在View中使用它,这将导致它实际显示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 MessageBoxes所需的全部内容。
以下代码只需在项目中实现一次,或者您可以将其放在可重用的共享库中。
将它添加到ViewModel基类中,以便可以从任何ViewModel中使用它:
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);
快乐的编码!
答案 1 :(得分:7)
我发现MVVM在程序员中引发了一连串强迫症(我从经验中知道)。这是好事。但是对于某些事情而言,努力是不值得的,特别是如果它引入了整个复杂的顺序,只是问用户“你确定你想要xxxx吗?”
我的观点是MessageBox.Show()可以从代码隐藏中调用,但从不调用ViewModel。在对话框与XAML更好地集成之前,只需点击即可,并且不要为此感到沮丧。它实际上是WPF UI设计当前状态的灰色区域。