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