Собственно вопрос. Были мысли сделать подобное через relative source, но как это передать в код - не знаю. Желательно с минимальным количеством кода, выходящего за пределы UserControl'a
Вопрос все равно туманный, поэтому я пройдусь по верхам.
Инициатор закрытия: ViewModel
ViewModel не знает про вид, а знает только о себе (ну и о инфраструктуре конечно) и потому может сообщить о необходимости "закрыть" только косвенно:
bool DialogResult {get;set;}
. (я предпочитаю это, особенно для диалоговых окон)Инициатор закрытия: вид
Можно получить текущее окно из контрола путем Window.GetWindow(this)
и вызвать у него Close() и будет эффект, как от кнопки закрытия окна со всеми вытекающими.
Вид знает о ViewModel и потому варианты "кто кого вызывает и опрашивает" ограничивает лишь фантазия. Я лучше приведу несколько примеров.
Окно с процессом операции. Закрытие запрещено
Определяем в окне хендлер события OnClosing и проверяя свойство вида vm.IsBusy отменяем закрытие окна e.handled = true
Окно с процессом операции. Остановить и закрыть
Обычно есть кнопка "Стоп". Биндим ее на команду vm CancelCommand, которая прервет операцию и по результату вызовет RequestClose, и окно закроется. Попутно полезно определить свойство IsStopping и отслеживая его через тригеры менять контент кнопки на "Останавливаемся..."
С кнопкой закрытия окна сложнее. Она вызваем OnClosing. В OnClosing достаем vm и вызываем у него какой нибудь vm.Cancel(). ViewModel прерывает операцию и вызывает RequestClose, на которую подписан вид. Вид получив уведомление от RequestClose закрывает себя Close() - и тут снова вызывается OnClosing (получается зацикливание). Поэтому OnClosing должен проверять флаг вьюмодели IsBusy, что никаких операций не происходит и можно закрыть. (Также можно получить deadlock, который придется разруливать через Task.Yield() - хоть где то он пригодился) Ну и конечно не забыть где нибудь написать "Останавливаемся..." если это не мгновенно.
Обычный диалог с формой и 2 кнопки: "Сохранить" и "Отмена"
Кнопку "Сохранить" биндим на команду SaveCommand. ViewModel при успешном результате вызывает RequestClose и окно закрывается. При неуспешном (например валидация) не вызывает.
Кнопку "Отмена" биндим на команду CancelCommand(CloseCommand), которая просто вызывает RequestClose и окно закрывается
Кнопки закрытия окна по хорошему тут быть не должно, но если есть, то она либо не вредит, если вся работа выполняется в UI, либо мудрить весь огород с OnClosing/IsBusy
ps: Не стоит забывать, что биндинг окна на DialogResult, работу с кнопкой "закрытия окна", Window.GetWindow(this).Close()
- все это можно скрыть за набором кастомных attached property и code-behind будет пуст
ps2: Если происходит асинхронная работа, то не забывать про защиту от повторного клика на кнопку/контрол или несвоевременного клика на кнопку "закрытия окна"
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Друзья, возможно кто-нибудь интегрировал ASPNET Core сервер и БД MySQL
У меня есть техническая документация, хранящаяся в файлах *bli, *
Прошу обратить внимание на строчку