Ответ 1
В Windows Forms или WPF без MVVM вы можете просто сказать 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 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);
Счастливое кодирование!