wpf 如何在 MVVM 中显示消息框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3705991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to show Messagebox in MVVM
提问by Jeevan Bhatt
Possible Duplicate:
How have you successfully implemented MessageBox.Show() functionality in MVVM?
I want to show message box in my MVVM WPF application. so from where to call MessageBox.Show().
我想在我的 MVVM WPF 应用程序中显示消息框。所以从哪里调用 MessageBox.Show()。
回答by Harlow Burgess
In Windows Forms, or WPF without MVVM, you could just say MessageBox.Show()and that was it! Wouldn't it be nice if you could do the same in MVVM?
在 Windows 窗体或没有 MVVM 的 WPF 中,您可以只说MessageBox.Show(),就是这样!如果你能在 MVVM 中做同样的事情不是很好吗?
Here is one way to do this - and it is as close as I can get to MessageBox.Show().
这是执行此操作的一种方法 - 它尽可能接近 MessageBox.Show()。
Here is the MVVM friendly 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
}
}
}
Tada!
多田!
Here is how it works:
下面是它的工作原理:
All that MessageBox_Show actually does is fire an event, so it is perfectly MVVM friendly. The ViewModel knows nothing about any view that may or may not be consuming it, and it doesn't perform the showing of a Windows MessageBox on it's own, so it can also be safely unit tested.
MessageBox_Show 实际上所做的只是触发一个事件,因此它非常适合 MVVM。ViewModel 对可能使用或不使用它的任何视图一无所知,并且它不会自行执行 Windows MessageBox 的显示,因此它也可以安全地进行单元测试。
To use it in a View, which will cause it to actually show a MessageBox, you just subscribe to the event and call e.Show() in the event handler, like this:
要在视图中使用它,这将导致它实际显示一个 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();
}
}
And that is all you need to do to show MVVM friendly Windows MessageBoxes.
这就是显示 MVVM 友好的 Windows MessageBoxes 所需要做的全部工作。
The code below only needs to be implemented once in your project, or you can put it in a reusable shared library.
下面的代码只需要在你的项目中实现一次,或者你可以把它放在一个可重用的共享库中。
Add this to your ViewModel base class so it can be used from any ViewModel:
将此添加到您的 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));
}
}
}
And then add the EventArgs class for the event handler:
然后为事件处理程序添加 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);
}
}
Unit testing is easy:
单元测试很简单:
target.AskTheQuestion();
target.ProcessTheAnswer(System.Windows.MessageBoxResult.Yes);
Happy Coding!
快乐编码!
回答by bufferz
I've found that MVVM invokes a streak of OCD in programmers (I know from experience). That's a good thing. But for certain things the effort just isn't worth it, especially if it introduces an entire order of complexity just to ask the user "Are you sure you wish to xxxx?"
我发现 MVVM 在程序员中引发了一系列的强迫症(我从经验中知道)。这是好事。但是对于某些事情,这种努力是不值得的,特别是如果它引入了整个复杂性只是为了问用户“你确定你想要 xxxx 吗?”
My opinion is that MessageBox.Show() may be called from the code-behind, but never the ViewModel. Until dialog boxes integrate better with XAML, just take the hit and don't feel bad about it. It's really a gray area of the current state of WPF UI design.
我的观点是 MessageBox.Show() 可以从代码隐藏中调用,但绝不能从 ViewModel 中调用。在对话框与 XAML 更好地集成之前,只需接受打击,不要为此感到难过。这确实是 WPF UI 设计当前状态的灰色区域。