Страницы

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

четверг, 21 марта 2019 г.

WPF Создание кастомного стиля окна с тенью

Задачей является создание кастомного стиля окна обладающего следующими свойствами:
Тень в четыре направления (left, top, right, bottom) Наличие хрома или, иначе, области за которую можно окно перетаскивать Возможность изменения размера окна мышью Тень приравнивается к областям, которые не имеют цвета на прозрачных окнах: это означает, что мы можем не только наблюдать за элементами других окон, которые находятся за тенью, но и работать с ними прямо сквозь тень (точно таким же свойством обладают окна с установленным в True свойством AllowsTransporency и не имеющего никакого цвета фона). Анимации сворачивания и разворачивания окон в Windows

Проблематика:
Хром окна всегда расположен сверху. Мы можем лишь задать его высоту (WindowChrome.CaptureHeight). Отсюда вытекает невозможность создания верхней тени, ведь она будет лишь фоном хрома и за неё можно будет потянуть окно. Решением может быть либо отрисовка тени на более низком уровне (WinApi; понятия не имею как), либо отказ от WindowChrome и использование Border, у которого есть обработчик MouseLeftButtonDown с вызовом в нём Window.DragMove метода. Пункт 4 их списка выше. Вот тут и идей я даже не имею. Разве что, опять же, рисовка тени окна на более низком чем WPF уровне... Анимацию сворачивания и разворачивания окна при WindowStyle в None не работают. Но можно сделать следующим образом: при сворачивании поменять стиль окна с None на любой другом, и, соответственно, при разворачивании делать наоборот. Но уж как-то совершенно в лоб. WindowChrome.ResizeBorderThickness позволяет задать толщину бордюра для ресайза окна. Но он и понятия никакого не имеет об отступах - там где у нас тень, там и будет расположен.


Ответ

У меня вот такой стиль убирает Chrome и оставляет тени:

Вот два окна, которые получаются в результате:

Жёлтое окно — стандартное, зелёное — стилизованное.
Обратите внимание, что белый прямоугольник в зелёном окне — часть стиля, его можно увидеть в шаблоне:

и убрать при желании.

Решение проблемы с максимизацией у меня выглядит так: добавляем имя:

и в триггеры:

Такое нужно потому, что окно в максимизированном состоянии размещается по координатам (-7, -7). (Информация из этого ответа.) Откуда взять константу 7 «цивилизованным путём», я пока не знаю. (Кажется, информация есть здесь.)

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

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