Страницы

Поиск по вопросам

пятница, 24 января 2020 г.

WPF: родительское окно над дочерними

#wpf #windows


В моем приложении имеется маленькое главное окно, из которого выполняется открытие
и управление другими окнами приложения. Необходимо сделать, чтобы это окно не перекрывалось
его дочерними окнами. Если же у дочерних окон в качестве Owner указывать это главное
окно, очевидно, что оно будет ими перекрываться.

Что я пробовал:


Не выстраивать иерархию окон (оставлять пустым поле Owner у дочерних окон), а главному
окну задать флаг TopMost=true. Но при этом рушится вся логика операционной системы
при сворачивании/разворачивании окон, необходимо ее реализовывать самостоятельно. В
этом случае появляется множество костылей по перехвату пользовательских операций. Имелись
различные проблемы со сбросом флага TopMost при деактивации приложения.
Сделать скрытое родительское окно для всех окон, а при активации любого окна приложения
указывать его в качестве Owner для главного окна. Тут тоже не обошлось без некоторых
костылей, но на этом методе я в данный момент остановился. В принципе, он уже длительное
время работает, но иногда WPF начинает сходить с ума - появляются исключения в его
внутренних методах. Например, иногда говорит о том, что нельзя менять флаг IsVisiblity
при закрытии окна, хотя у меня в код закрытия ни прямо, ни косвенно не работает с ним.
Подозреваю, что это связано частой сменой значения Owner для главного окна, т.к. если
не менять его, проблема не проявляется.


Сейчас активно рассматриваю вариант с одним прозрачным окном, развернутым на весь
экран с Canvas и реализацией дочерних окон в виде элементов этого окна. Это решает
практически все проблемы, но появляется другая - работа с несколькими мониторами (а
окна приложения должны иметь возможность располагаться на разных мониторах). Особенно
проблемным становится вариант, когда мониторы пользователя имеют разное разрешение и DPI.

Уверен, такая задача возникла не у меня первого. Подскажите, как ее можно решить
еще? Нужно хотя бы общее направление.
    


Ответы

Ответ 1



В Вашем случае наиболее рационально будет всё же идти по первому пути (оставлять поле родителя пустым) и реализовывать логику сворачивания, разворачивания и тд и тп самостоятельно. Например, через события. Если вы реализовали MVVM, то логично и наиболее правильно будет обрабатывать и инициировать события при помощи mvvm-мессенджера. Какую из библиотек выбрать - решайте сами. Если используете Prism, то там уже есть встроенный мессенджер. Если обошлись без Prism и реализовали MVVM самостоятельно, то попробуйте EventBroker от Appccelerate.

Комментариев нет:

Отправить комментарий