WPF и Prism View Overlay

Мне нужна помощь с наложением представлений с использованием призменного фреймворка. Это немного сложнее, чем это, поэтому позвольте мне объяснить. Я мог бы также обдумать это:D

у меня есть оболочка (окно wpf), и у меня есть 2 представления (A & B - оба пользовательских элемента управления) в модуле. когда оболочка загружается, она загружает представление A. На представлении A у меня есть кнопка для "всплывающего" представления B для некоторого пользовательского ввода. Естественно, я бы подумал о каком-то модальном окне / элементе управления, возможно даже всплывающем окне. однако проблема, с которой я сталкиваюсь во всплывающем окне, заключается в том, что при перемещении оболочки всплывающее окно остается фиксированным и не блокирует события в представлении A. Я попытался отключить представление A, чтобы остановить запуск событий, и я также попытался использовать a для получить представление B двигаться с оболочкой. Работает только холст, но теперь мне нужен способ его заблокировать ". Могу ли я наложить вид поверх другого вида на призму? или как все остальные создают модальные всплывающие окна с помощью призмы и wpf? Любой совет или указатели будут с благодарностью.

2 ответа

Решение

Если вы хотите использовать встроенные диалоговые окна без дополнительного окна, вы можете использовать RegionManager Prism для достижения описанного поведения. Хитрость заключается в том, чтобы поместить область PopUp параллельно вашей основной области в визуальном дереве:

<Grid>
   <ContentControl cal:RegionManager.RegionName="MainRegion" IsEnabled={Binding IsNoPopUpActive} />
   <ContentControl cal:RegionManager.RegionName="PopUpRegion"/>
</Grid>

Теперь используйте RegionManager, чтобы поместить представление "A" в "MainRegion". Создайте класс контроллера, похожий на IPopUpDialogController. Он должен отвечать за размещение вашего представления "B" (или любого другого PopUpView в вашем приложении) в "PopUpRegion" по требованию. Кроме того, он должен управлять флагом, который сигнализирует о включении или отключении основного "MainRegion". Таким образом, пользователь не сможет играть с элементами управления в вашем представлении "А", пока всплывающее окно не закроется.

Это можно сделать даже модально, используя ComponentDispatcher.PushModal(), прежде чем помещать фрейм в Dispatcher. Тем не менее, я бы рекомендовал избегать модальных диалогов.


Обновление: Как было запрошено в комментарии, IsNoPopUpActive может быть реализован в модели представления поддержки. Там вы можете связать его с коллекцией View RegionManager для всплывающего региона:

public bool IsNoPopUpActive 
{ 
    get { return _regionManager.Regions["PopUpRegion"].Views.Count() == 0; }
}

Не забудьте вызвать событие PropertyChanged, как только вы измените коллекцию представлений (добавьте / удалите всплывающее окно).

Просто для вашей информации: в настоящее время я избегаю отключения элементов управления в фоновом режиме и вместо этого вставляю прозрачную панель. Это позволяет избежать нажатия на фоновые элементы управления. Тем не менее, это не обрабатывает ввод с клавиатуры (вкладки для элементов управления). Чтобы исправить ввод с клавиатуры, необходимо убедиться, что фокус клавиатуры зафиксирован во всплывающем окне ( MSDN на концепциях WPF Focus).

Добавление следующих атрибутов фокуса в область всплывающих окон должно помочь:

KeyboardNavigation.DirectionalNavigation="None"
KeyboardNavigation.ControlTabNavigation="None"
KeyboardNavigation.TabNavigation="Cycle"
KeyboardNavigation.TabIndex="-1"

Если вы используете WPF + MVVM с Prism, вы можете взглянуть на этот оверлейный контроллер просмотра сообщений. Приятной частью этого подхода является то, что вы можете написать модульные тесты для вашей модели представления, используя контроллер оверлея оверлея, и заставить контроллер макета вернуть результат, который пользователь выберет в оверлее.

Вы можете найти его здесь: http://presentationlayer.wordpress.com/2011/05/24/wpf-overlay-message-view-controller/

Надеюсь это поможет

Другие вопросы по тегам