Предположим есть окно в котором в виде таблице отображается некий список, для каждой записи есть некий набор действий, для примера пусть будут "Edit"/"Detail"/"Delete"
При выборе пользователем пункта "Delete" необходимо показать окно с неким предупреждающим текстом, и двумя возможными действиями: "Ok"/"Cancel"
Как бы я это сделал в winforms приложении:
var dialogBox = new DialogBox.ShowModal();
if(dialogBox.DialogResult == DialogResult.Ok)
{
//здесь код который должен быть сделан в случае подтверждения действия
}
//здесь то что надо сделать в случае отмены
В рамках mvvm, необходимо сделать View, ModelView, т.е. у нас должно быть что то типа Main, MainViewModel, Dialog, DialogViewModel
в Main - будут кнопки которые будут прибиндины к командам из ViewModel. т.е. например так могла бы выглядеть команда для "Delete"
private void Delete()
{
var dialog = new Dialog(new DialogViewModel())
dialog.Show();
//здесь как то надо сделать проверку на то что случилось в диалоге
}
Как вариант можно сделать публичное свойство в DialogViewModel с типом boolean и устанавливать его в диалоге, по нажатии на любую из кнопок (Ok/Canсel) менять его значение, в главной форме смотреть значение этого свойства. Вот только меня терзают сомнения в правильности такого подхода.
Как сделать Диалоговое окно в wpf с использованием mvvm?
P.S.: код писал здесь, могут быть ошибки
Ответ
Здесь есть два варианта действий:
Более простой способ, но более неудобный в случае, если вы используете TDD: Вам нет необходимости создавать ViewModel и View отдельно для диалогового окна: достаточно перед удалением проверять ответ пользователя в диалоговом окне следующим образом:
if (MessageBox.Show("Are you sure want to delete item?", "Delete confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
modelInstance.Delete(); //execute delete
}
Более трудоёмкий способ, но с соблюдением всех канонов MVVM: создаёте ViewModel для вашего диалогового окна. Во ViewModel создаёте событие, например:
public event EventHandler ConfirmEvent;
Событие нужно декорировать специальным аттрибутом, который позволит транслировать его в другие ViewModel-классы, не нарушая при этом принцип high-cohesion loose-coupling. Для этого используются мессенджеры. Можете попробовать Appcelerate.EventBroker. В своих проектах я использую именно его.
Далее - создаёте команду, которая ссылается на метод, вызывающий вышеупомянутое событие. Привязываете команду к кнопке в вашем диалоговом окне.
private ICommand confirmCommand;
public ICommand ConfirmCommand
{
get
{
if(confirmCommand==null)
{
confirmCommand = new Command(p => FireConfirmEvent(), p => ConfirmEventPredicate());
}
return confirmCommand;
}
}
В самом окне при помощи метода, декорированного аттрибутом из того же мессенджера обрабатываете это событие. Метод будет содержать код, выполняющий удаление.
View в этом случае создавайте, как пару Window.xaml + Window.cs, у которого есть метод ShowDialog(), что автоматически заблокирует вызывающее окно на время открытия диалогового.
PS: первый способ не совсем правильный, потому что будет сложно тестировать результат, выбранный пользователем в MessageBox.
Добавлено
Если захотите использовать это окно в разных местах вашего приложения, создайте базовый абстрактный класс, а в унаследованных VM-классах перегрузите нужные вам свойства. Например, в некоторых случаях вам может понадобиться «дернуть» несколько событий, чтобы на подтверждение среагировало несколько ViewModel. Тут всё зависит от сложности проекта.
Комментариев нет:
Отправить комментарий