Есть два хороших способа сделать это: 1) сервис диалога (простой, чистый) и 2) вспомогательный просмотр. View Assisted предоставляет некоторые полезные функции, но, как правило, не стоит.
ДИАЛОГ СЕРВИС
a) интерфейс службы диалога, например, через конструктор или некоторый контейнер зависимостей:
interface IDialogService
{
Task ShowDialogAsync(DialogViewModel dlgVm);
}
b) Ваша реализация IDialogService должна открыть окно (или внедрить некоторый элемент управления в активное окно), создать представление, соответствующее имени данного типа dlgVm (использовать регистрацию или соглашение контейнера или ContentPresenter с типом DataTemplates, связанным с типом) , ShowDialogAsync должен создать TaskCompletionSource и вернуть его .Task proptery. Класс DialogViewModel сам нуждается в событии, которое вы можете вызвать в производном классе, когда хотите закрыть, и посмотреть в диалоговом окне, чтобы фактически закрыть / скрыть диалоговое окно и завершить TaskCompletionSource.
b) Для использования просто вызовите await this.DialogService.ShowDialog (myDlgVm) в вашем экземпляре некоторого производного от DialogViewModel класса. После возвращения await посмотрите на свойства, которые вы добавили в диалоговую виртуальную машину, чтобы определить, что произошло; вам даже не нужен обратный звонок.
ПОМОЩЬ ВИДА
Это ваш взгляд на прослушивание события в модели представления. Все это может быть заключено в Blend Behavior, чтобы избежать выделения кода и использования ресурсов, если вы так склонны (FMI, подкласс класса «Behavior», чтобы увидеть своего рода Blendable присоединенное свойство на стероидах). Сейчас мы сделаем это вручную для каждого представления:
a) Создайте OpenXXXXXDialogEvent с пользовательской полезной нагрузкой (производный класс DialogViewModel).
б) Пусть представление подписывается на событие в своем событии OnDataContextChanged. Не забудьте скрыть и отписаться, если старое значение! = Null и в событии Unloaded окна.
в) Когда событие запускается, откройте представление, которое может находиться в ресурсе на вашей странице, или вы можете найти его по соглашению в другом месте (как в подходе службы диалога).
Этот подход более гибкий, но требует больше работы для использования. Я не пользуюсь этим много. Одним приятным преимуществом является, например, возможность размещать представление физически внутри вкладки. Я использовал алгоритм, чтобы поместить его в границы текущего пользовательского элемента управления или, если он недостаточно велик, перемещаться по визуальному дереву, пока не будет найден достаточно большой контейнер.
Это позволяет диалоговым окнам быть ближе к месту, где они фактически используются, только затемняет часть приложения, связанную с текущей активностью, и позволяет пользователю перемещаться внутри приложения без необходимости вручную отталкивать диалоги, даже если несколько квази-модальных диалоговых окон, открытых на разных вкладках или вложенных представлениях.