- Окна нестандартной формы
- Стили и шаблоны элемента Window Window Styles and Templates
- Части окна Window Parts
- Состояния окна Window States
- Пример для ControlTemplate окна Window ControlTemplate Example
- Шаблон окна
- Стили, триггеры и темы
- Стили
- TargetType
- Определение обработчиков событий с помощью стилей
- Наследование стилей и свойство BasedOn
- Изменение стиля окна WPF
- 1 ответ 1
- Примечания
Окна нестандартной формы
Окна необычной формы часто являются товарным знаком современных прикладных приложений вроде редакторов фотографий, программ для создания кинофильмов и МРЗ-проигрывателей; скорее всего, они будут встречаться в WPF-приложениях даже более часто.
В создании базового приложения нестандартной формы в WPF нет ничего сложного. Однако создание привлекательного профессионально выглядящего окна необычной формы требует немалых усилий — и, нередко, привлечения талантливого дизайнера графики для создания эскизов и фоновой графики.
Базовая процедура для создания окна нестандартной формы подразумевает выполнение следующих шагов:
Установите для свойства Window.AllowsTransparency значение true.
Установите для свойства Window.WindowStyle значение None, чтобы скрыть не клиентскую область окна (рамку голубого цвета). Если этого не сделать, при попытке показать окно появится ошибка InvalidOperationException.
Установите для фона (свойства Background) прозрачный цвет (цвет Transparent, значение альфа-канала которого равно нулю). Или же сделайте так, чтобы для фона использовалось изображение, имеющее прозрачные области (с нулевым значением альфа-канала).
Эти три шага эффективно удаляют стандартный внешний вид окна. Для обеспечения эффекта окна необычной формы далее необходимо предоставить какое-то непрозрачное содержимое, имеющее нужную форму. Здесь возможны перечисленные ниже варианты:
Предоставить фоновую графику, используя файл такого формата, который поддерживает прозрачность. Например, для фона можно использовать файл PNG. Это простой прямолинейный подход, и он очень удобен, если приходится работать с дизайнерами, которые не разбираются в XAML. Однако из-за того, что окно будет визуализироваться с большим количеством пикселей и более высокими системными параметрами DPI фоновая графика может приобрести искаженный вид. Это также может представлять проблему и в случае разрешения пользователю изменять размеры окна.
Использовать доступные в WPF функции для рисования формы, чтобы создать фон с векторным содержимым. Такой подход исключает потерю качества, какими бы ни были размеры окна и настройка DPI системы. Однако в этом случае наверняка потребуется использовать средство проектирования, поддерживающее XAML, такое как Expression Blend.
Использовать более простой WPF-элемент, имеющий необходимую форму. Например, окно с замечательными скругленными углами можно создать с помощью элемента Border. Такой подход позволяет создавать окна с современным внешним видом в стиле Office без применения каких-либо дизайнерских навыков.
Ниже в качестве примера приведен код создания пустого прозрачного окна с применением первого подхода и предоставлением файла PNG для прозрачных областей:
Это окно необычной формы (состоящее из окружности и квадрата) имеет не только пробелы, сквозь которые может просматриваться находящееся за ним содержимое, но кнопки, которые выходят за границы изображения и накладываются на прозрачную область, из-за чего кажется, будто бы они существуют сами по себе, без окна:
Те, кому приходилось программировать с использованием Windows Forms ранее, наверняка заметят, что окна нестандартной формы в WPF имеют более четкие края, особенно на изгибах. Все дело в том, что WPF умеет выполнять сглаживание между фоном окна и находящимся за ним содержимым для создания более гладкого края.
Ниже показано другое, более простое окно необычной формы. В этом окне используется элемент Border со скругленными углами для придания окну отчетливого внешнего вида. Компоновка тоже является упрощенной, поскольку исключает случайный выход содержимого за пределы границы, а размер границы может легко изменяться без наличия элемента Viewbox:
В этом окне содержится элемент Grid с тремя строками, которые используются для строки заголовка, строки нижнего колонтитула и размещаемого между ними содержимого. В строке с содержимым находится еще один элемент Grid, который имеет другой фон и может содержать другие необходимые элементы (в текущий момент в нем находится только один единственный элемент TextBlock).
Для завершения внешнего вида этого окна осталось создать только кнопки, имитирующие размещаемые в правом верхнем углу стандартные кнопки для разворачивания, сворачивания и закрытия окна.
Источник
Стили и шаблоны элемента Window Window Styles and Templates
В этом разделе описываются стили и шаблоны для Window элемента управления. This topic describes the styles and templates for the Window control. Можно изменить значение по умолчанию, ControlTemplate чтобы обеспечить уникальность внешнего вида элемента управления. You can modify the default ControlTemplate to give the control a unique appearance. Дополнительные сведения см. в разделе Создание шаблона для элемента управления. For more information, see Create a template for a control.
Части окна Window Parts
WindowЭлемент управления не имеет именованных частей. The Window control does not have any named parts.
Состояния окна Window States
В следующей таблице перечислены визуальные состояния Window элемента управления. The following table lists the visual states for the Window control.
Имя VisualState VisualState Name | Имя VisualStateGroup VisualStateGroup Name | Описание Description |
---|---|---|
Допустимо Valid | ValidationStates ValidationStates | Элемент управления использует Validation класс, а Validation.HasError присоединенное свойство — false . The control uses the Validation class and the Validation.HasError attached property is false . |
InvalidFocused InvalidFocused | ValidationStates ValidationStates | Validation.HasErrorПрисоединенное свойство имеет true фокус. The Validation.HasError attached property is true has the control has focus. |
InvalidUnfocused InvalidUnfocused | ValidationStates ValidationStates | Validation.HasErrorПрисоединенное свойство true имеет элемент управления, не имеющий фокуса. The Validation.HasError attached property is true has the control does not have focus. |
Пример для ControlTemplate окна Window ControlTemplate Example
В следующем примере показано, как определить ControlTemplate для Window элемента управления. The following example shows how to define a ControlTemplate for the Window control.
ControlTemplateИспользует один или несколько следующих ресурсов. The ControlTemplate uses one or more of the following resources.
Источник
Шаблон окна
С помощью показанного до сих пор кода можно довольно легко создавать окна особой формы. Однако если нужно использовать новый стандарт окон для всего приложения, придется вручную стилизовать каждое окно, оснащая его границей одинаковой формы, областью заголовка, кнопками для закрытия и т.д. В такой ситуации удобнее поместить код разметки в шаблон элемента управления и затем использовать этот шаблон в отношении любого окна.
Первым делом нужно изучить предлагаемый по умолчанию шаблон элемента управления для класса Window. В основном он довольно прост, но включает в себя одну, возможно, неожиданную деталь — элемент AdornerDecorator. Этот элемент создает поверх остальной части клиентского содержимого окна специальную область рисования, называемую . Элементы управления WPF могут использовать этот слой для прорисовывания содержимого, которое должно налагаться поверх других элементов.
К такому содержимому относятся небольшие графические индикаторы, отражающие фокус, помечающие ошибки проверки достоверности и указывающие путь при операциях перетаскивания. При создании специального окна необходимо позаботиться о наличии декоративного слоя, чтобы использующие его элементы управления могли продолжать функционировать.
После этого можно приступать к определению базовой структуры, которую должен иметь шаблон окна. Ниже показан стандартный пример разметки, в которой предполагается создание окна, подобного показанному в предыдущей статье:
Элементом самого верхнего уровня в данном шаблоне является объект Border, который отвечает за рамку окна. Внутри него размещается элемент Grid с тремя строками. Содержимое элемента Grid распределяется следующим образом:
В самой верхней строке размещается строка заголовка, которая состоит из обычного элемента TextBlock, отображающего заголовок окна и кнопку закрытия. Привязка шаблона извлекает заголовок окна из свойства Window.Title.
В средней строке размещается вложенный элемент Border с остальной частью содержимого окна. Это содержимое вставляется с использованием элемента Content Presenter. Элемент ContentPresenter помещается в оболочку AdornerDecorator, что гарантирует размещение поверх него декоративного слоя.
В третьей строке размещается еще один элемент ContentPresenter. Он извлекает свое содержимое не из свойства Window.Content с помощью стандартной привязки, а получает его явно из свойства Window.Tag. Обычно это содержимое представляет собой обычный текст, но может включать любой другой элемент.
Свойство Tag используется потому, что в классе Window не предусмотрено свойства, предназначенного для указания текста нижнего колонтитула. Другим возможным вариантом является создание специального класса, унаследованного от Window, и добавление к нему дополнительного свойства Footer.
В третьей строке также размещается элемент захвата и изменения размера. Он отображается триггером, когда свойство Window.ResizeMode установлено в CanResizeWithGrip.
И, наконец, последними идут два невидимых прямоугольника, которые размещаются вдоль правого и нижнего края элемента Grid (и, соответственно, самого окна). Они позволяют пользователю изменять размеры окна щелчком и перетаскиванием.
В этом коде разметки не показаны малоинтересные стили элемента захвата и изменения размера (просто создает небольшой узор из точек) и кнопки закрытия окна (рисует небольшой символ X в красном квадрате). Разметка также не включает детали форматирования наподобие градиентной кисти, отвечающей за прорисовку фона, и свойств, отвечающих за создание скругленных углов границы окна.
Шаблон окна применяется с использованием простого стиля. Стиль также устанавливает три ключевых свойства класса Window, которые делают его прозрачным. Это позволяет создать границу окна и фон с помощью элементов WPF.
Здесь имеется лишь одна проблема. В настоящий момент окно не обладает большей частью базового поведения, которое требуется окнам. Например, его нельзя ни перетаскивать по рабочему столу, ни изменять в размерах, ни закрывать с помощью соответствующей кнопки. Для выполнения этих действий необходим соответствующий код.
Существует два возможных способа для добавления необходимого кода: расширение примера до специального класса, производного от Window, либо создание класса отделенного кода для словаря ресурсов. Подход с созданием специального класса лучше с точки зрения инкапсуляции и позволяет расширять общедоступный интерфейс окна (например, добавлять полезные методы и свойства, пригодные для использования в приложении).
Подход с созданием класса отделенного кода является относительно облегченной альтернативой и позволяет расширить возможности шаблона элемента управления, сохранив за приложением возможность продолжать пользоваться базовыми классами элементов управления.
Источник
Стили, триггеры и темы
Стили
Стили позволяют определить набор некоторых свойств и их значений, которые потом могут применяться к элементам в xaml. Стили хранятся в ресурсах и отделяют значения свойств элементов от пользовательского интерфейса. Также стили могут задавать некоторые аспекты поведения элементов с помощью триггеров. Аналогом стилей могут служить каскадные таблицы стилей (CSS), которые применяются в коде html на веб-страницах.
Зачем нужны стили? Стили помогают создать стилевое единообразие для определенных элементов. Допустим, у нас есть следующий код xaml:
Зесь обе кнопки применяют ряд свойств с одними и теми же значениями:
Однако в данном случае мы вынуждены повторяться. Частично, проблему могло бы решить использование ресурсов:
Однако в реальности код раздувается, опть же приходится писать много повторяющейся информации. И в этом плане стили предлагают более элегантное решение:
Результат будет тот же, однако теперь мы избегаем не нужного повторения. Более того теперь мы можем управлять всеми нужными нам свойствами как единым целым — одним стилем.
Стиль создается как ресурс с помощью объекта Style , который представляет класс System.Windows.Style . И как любой другой ресурс, он обязательно должен иметь ключ. С помощью коллекции Setters определяется группа свойств, входящих в стиль. В нее входят объекты Setter , которые имеют следующие свойства:
Property : указывает на свойство, к которому будет применять данный сеттер. Имеет следующий синтаксис: Property=»Тип_элемента.Свойство_элемента» . Выше в качестве типа элемента использовался Control, как общий для всех элементво. Поэтому данный стиль мы могли бы применить и к Button, и к TextBlock, и к другим элементам. Однако мы можем и конкретизировать элемент, например, Button:
Value : устанавливает значение
Если значение свойства представляет сложный объект, то мы можем его вынести в отдельный элемент:
TargetType
Hам необязательно прописывать для всех кнопок стиль. Мы можем в самом определении стиля с помощью свойства TargetType задать тип элементов. В этом случае стиль будет автоматически применяться ко всем кнопкам в окне:
Причем в этом случае нам уже не надо указывать у стиля ключ x:Key несмотря на то, что это ресурс.
Также если используем свойство TargetType, то в значении атрибута Property уже необязательно указывать тип, то есть Property=»Control.FontFamily» . И в данном случае тип можно просто опустить: Property=»FontFamily»
Если же необходимо, чтобы к какой-то кнопке не применялся автоматический стиль, то ее стилю присваивают значение null
Определение обработчиков событий с помощью стилей
Кроме коллекции Setters стиль может определить другую коллекцию — EventSetters , которая содержит объекты EventSetter . Эти объекты позволяют связать события элементов с обработчиками. Например, подключим все кнопки к одному обработчику события Click :
Соответственно в файле кода c# у нас должен быть определен обработчик Button_Click:
Наследование стилей и свойство BasedOn
У класса Style еще есть свойство BasedOn , с помощью которого можно наследовать и расширять существующие стили:
Cвойство BasedOn в качестве значения принимает существующий стиль, определяя его как статический ресурс. В итоге он объединяет весь функционал родительского стиля со своим собственным.
Источник
Изменение стиля окна WPF
Как создать единый стиль окна разрабатываемого приложения для всех версий ОС одинаковое?
Просмотрел различные статьи, но все варианты не подходят, тк там утрачивается возможность расширять окно и переносить его по экрану.
Подскажите, пожалуйста, как создать кастомный стиль окна WPF не потеряв весь основной функционал, и иметь возможность переносить его и менять размер?
1 ответ 1
Примечания
Значит, полагаю, вы в этой теме новичок (раз в коменты кинули курсы вам) и вам не мешало бы всё «разложить по полочкам».
Значит, поскольку вам нужен одинаковый вид окна на разных версиях Windows, без переопределения фрейма тут не обойтись. Можно его вообще убрать и нарисовать свой (установить WindowStyle в None ), но мы воспользуемся более грамотным решением: используем специальный для этого класс — WindowChrome при этом не меняя WindowStyle (хотя это без разницы, просто так сохраняются стандартные анимации сворачивания/разворачивания Windows).
За ширину границы изменения размера окна отмечает WindowChrome.ResizeBorderThickness . GlassFrameThickness можно установить в -1 для включения стандартной тени окна, но тогда на системах Windows 10 где ppi выше 130 будет сильно наблюдаться эффект искажения текста — не советую.
CaptionHeight — высотка заголовка окна, т.е. области, за которую можно «потащить окно».
Кнопочки сами нарисуете.
Вообще, почитайте это, а так же можете в мой профиль зайти — там много тем с переопределением шаблонов окон.
Источник