Как сделать круглые кнопки c wpf
Перейти к содержимому

Как сделать круглые кнопки c wpf

  • автор:

Как сделать круглые кнопки c wpf

Всем привет. Когда я только начал знакомится с WPF, одним из первых моих заданий было создание нестандартной кнопки. Самая элементарная и, наверное, самая популярная сейчас – это круглая форма. Поэтому следуя моде на Modern UI , я решил сделать такую-же кнопку.

Обычную «одноразовую» кнопку можно создать и так:

Все. Кнопка готова. Она круглая и иконка есть. Проблема в том, что для каждой кнопки придется делать такой копипаст, а это и неудобно и некрасиво. Пример правильный, только нужно вынести шаблон в ресурсы и применять его к каждой кнопке.
Так и сделаю, но сначала опишу требования, которые я поставил перед своей кнопкой:

  1. Иконка должна быть векторная;
  2. Реализовать нужные привязки, что бы кнопка могла менять размеры и цвета;
  3. Все это должно красиво выглядеть;

Изначально, думал сразу же писать код, но желание нарисовать иконку меня перебороло. Поэтому сделаю небольшое отступление и создам иконку. Ни, или несколько…

Знаю, многие скажут, что то вроде «Не программиста это дело — иконки рисовать». Может и так, но я люблю рисовать, создавать дизайн своих программ, и уж тем более контролировать этот процесс, если кто-то мне помогает )). Может, сказалось, то, что я вырос в семье художников? Ну, или то, что я и сам на художника учился, до того как программированием не занялся 🙂 пропустить создание иконки

Создание иконки

Выберем графический редактор. Например, Adobe Illustrator , Microsoft Expression Design и т.д. Я буду использовать CorelDRAW , а переведу в xaml уже в Design . Странная комбинация получилась, но никак руки не доходили познакомиться с Design как следует.

Открываем Corel , создаем новый проект – рисуем. Можете нарисовать стандартную геометрическую фигуру, звездочку или стрелочку. Правда, если речь идет о чем то таком простом, то проще это нарисовать в самом WPF .

Я нарисовал иконку. Что дальше?
Нужно сохранить ее в векторном формате. Выбираем Экспорт и сохраняем, например в emf . Что бы перевести иконку в xaml я использую программу Microsoft Expression Design . Она входит в пакет Microsoft Expression Studio.

Открываем иконку. Находим Экспорт . В появившемся окне выбираем нужный формат. Я выбрал XAML WPF Resource Dictionary .

Дальше, в WPF проекте создаем Resource Dictionary с именем Icons . Туда копируем генерируемую разметку иконки. Можно и не создавать отдельный файл, а записать все в ресурсы окна или приложения, но лучше структурировать сразу. Тогда можно держать все свои иконки в отдельной библиотеке и с легкостью переносить в другие проекты.

Можно создать в библиотеке Icons ресурс SolidColorBruch и, там где иконки будут одноцветные, задать его в Brush свойства. Потом, если нужно будет поменять цвет иконкам, достаточно будет изменить свойство Color в этом ресурсе. Хотя, думаю, все зависит от ваших личных предпочтений.

Библиотека Icons , пока с одной иконкой:

      " Geometry=""/>     

Значение свойства Geometry я сознательно стер с примера – слишком много лишнего получилось бы. Скажу только, что там укороченная запись геометрических путей, из которых состоит иконка. Детально, можете посмотреть на msdn.

Иконка создана. Можно вернуться к кнопке…

Круглая кнопка

Что я узнал, покопавшись в интернете, посмотрев исходники?

У каждой кнопки есть свойство Content . Это очень удобное свойство, так как влияет на внешний вид, всего, что наследуется от ContentControl (кнопка его потомок), через шаблон. Поэтому у кнопки может быть любое содержимое. Например, кнопка с обычным текстом содержит TextBlock , на которой и отображается на самом деле текст кнопки. Или опять же в Content можно поместить контейнер, в котором может быть все что угодно.

Создаем папку Themes , а в ней generic.xaml . И шаблон кнопки:

    

Теперь, если кнопке задать стиль BubleButton , то она примет форму обычного эллипса.

Пара моментов:

  • StrokeThickness принимает значение только одно, а у BorderThickness четыре значения, так что нужно присвоить одно из них.
  • Если кнопке не задать Background , то при нажатии на пустое пространство внутри круга, ничего не случится (обработчик события кнопки не сработает), поэтому его придется задать .

Теперь я добавлю в Grid шаблона Rectangle , и привяжу к свойству Fill Content кнопки:

И разметка кнопки в окне:

 " Height="100" Width="100" BorderThickness="2" Background="" Foreground="WhiteSmoke" Content="" /> 

Результат меня как-то не впечатлил. Иконка одного размера с кнопкой (

Первое, что пришло на мысль, задать фиксированный размер для Rectangle . Но тогда и кнопка должна быть точного размера. Но, все-таки, можно сделать иконку, скажем, 80% от размера кнопки. Привязки позволяют нам это сделать с помощью конвертеров . Название говорит само за себя.

Я создал класс ScaleConverter , который реализует интерфейс IValueConverter :

class ScaleConverter : IValueConverter < public double Scale < get; set; >public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) < double num = (double)value; return (num * (Scale / 100)); >public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) < return null; >>

Дополненный вариант шаблона, с применением конвертера ScaleConverter :

    

Можно еще добавить эффект, который будет при наведении на кнопку.
Например, задать для Grid Opacity = «.8» , а в ControlTemplate создать триггер:

Стиль кнопки готовый. Векторная иконка, изменение размера, эффект при наведении. Красиво?

Ну, относительно. Хотелось же, помимо размера, свободно изменять и цвет. Если для Ellipse можно спокойно менять и Stroke через Foreground и Fill через Background кнопки, то, как изменить цвет иконки? Первое о чем я сразу же подумал ContentConverter .

Перед тем как присвоить DrawingBrush , достать из него все GeometryDrawing и поменять им свойства Brush .

Испробовав ( ну конечно! ) это извращение , я был немого разочарован, когда узнал что GeometryDrawing нельзя редактировать. За это отвечает свойство IsFrozen . Если оно возвращает true , то объект заморожен и доступен только для чтения. И действительно, я же питался изменить цвет ресурса, для конкретной кнопки. Но можно создать копию, у которой по умолчанию IsFrozen равно false , изменить уже в ней нужные свойства и вернуть в качестве результата ))).

Это сработает, но показывать уже не буду, так как то, что я описал, показалось мне настолько корявым, что лучше отказаться от изменения цвета. Да и спихнуть все на то, что обычно в приложениях кнопки определенного цвета всегда можно 🙂

Опишу еще один вариант шаблона. Мне он показался более красивым и удачным решением, чем предыдущий шаблон:

И все-таки создаем ContentConverter . Хотя цель его будет не та что описана ранее. Код конвертера:

class ContentConverter : IValueConverter < public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) < DrawingGroup draw = (value as DrawingBrush).Drawing as DrawingGroup; PathGeometry path = new PathGeometry(); foreach (GeometryDrawing item in draw.Children) < path.AddGeometry(item.Geometry); >return path; > public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) < return null; >>

Здесь возвращается PathGeometry , который содержит всю геометрию иконки.
И полная разметка нового шаблона с ContentConverter и применением геометрии:

  

Теперь можно менять и размер, и цвет иконки. А еще получился красивый эффект при наведении.

Думаю, что теперь кнопка соответствует всем требованиям, что я поставил в начале. Поэкспериментируйте с исходниками сами. Буду рад услышать ваше мнение.

Шаблоны элементов управления

Даже самый простой стиль в действительности служит не более чем контейнером для установок общих свойств элемента управления определенного типа. Несмотря на всю пользу, которую стили приносят для упрощения настройки многих свойств (цвета, размера шрифта и т.д.) элементов управления целевого типа, общий порядок визуалиции элементов управления остается прежним. Поэтому, независимо от характера стилевого оформления элемента управления типа Button, он все равно имеет форму прямоугольной, а возможно, и квадратной кнопки.

Иногда возникает потребность создать стиль, который не только изменяет ряд уставок общих свойств целевого элемента управления, но и переопределяет форму самого элемента управления. Так, в конкретном проекте может потребоваться круглая форма кнопки или произвольная многоугольная форма, нарисованная инструментом Pen или Pencil.

Когда требуется создать стиль, способный изменить геометрическую форму визуализируемого элемента управления, этот стиль приходится определять таким образом, чтобы он содержал встроенный шаблон элемента управления, описываемый в разметке XAML элементом . А в этом элементе разметки можно определить внешний вид нового элемента управления, воспользоваться диспетчерами компоновки для доступа к их содержимому и выполнить ряд других типичных операции.

Несмотря на то что шаблон является наиболее часто используемой составляющей более крупного стиля, имеется все же возможность определить автономный ресурс объекта в элементе разметки . Настраивая свойство Template (Шаблон) элементов управления, можно назначать для них заданные шаблоны. В следующем примере проекта будет показано, как это делается.

По умолчанию внешний вид каждого элемента управления на платформах WPF и Silverlight визуализируется с помощью связанного с ними шаблона, используемого по умолчанию. Например, шаблон, используемый по умолчанию для элемента управления типа Button, содержит инструкции по визуализации так хорошо знакомой вам прямоугольной формы кнопки. По этому же принципу визуализируются все остальные элементы управления на платформах WPF и Silverlight.

Используемые по умолчанию шаблоны входят в состав библиотек на платформах WPF и Silverlight в качестве встраиваемых XAML-ресурсов, и поэтому не могут быть изменены непосредственно. Но, как будет показано далее, в среде Expression Blend предоставляется ряд механизмов для извлечения копии используемого по умолчанию шаблона с целью его последующей правки.

Помимо определения различных инструкций по визуализации общего внешнего элемента управления, шаблон содержит также инструкции по реагированию элемента управления на действия пользователя и прочие изменения состояния. Например, в шаблоне, используемом по умолчанию для элемента управления типа Button, описывается, каким образом должна выглядеть кнопка, когда она получает логическии фокус, когда производится щелчок в пределах ее границ, когда она становится неактивной, и в прочих состояниях.

Для определения нового шаблона (или видоизменения уже имеющегося), как правило, требуется предоставлять специальные элементы разметки XAML, описывающие реакцию элемента управления на те же самые изменения состояния. Как будет показано далее, в шаблоне на платформе WPF можно определить визуальные подсказки используя два следующих средства: триггеры или диспетчер визуальных состояний (VSM — Visual State Manager), тогда как на платформе Silverlight это можно сделать только с помощью диспетчера VSM. Далее будет также показано, что в среду Ехpression Blend интегрированы специальные редакторы, предназначенные для работы с каждым из этих двух средств.

Диспетчер VSM был впервые введен в состав прикладного интерфейса Silverlight API и служит для внедрения визуальных подсказок в шаблон на платформе Silverlight. Исторически сложилось так, что программирующие на платформе WPF применяли аналогичный подход посредством триггеров. Но после выпуска версии .NET 4.0 платформа WPF была обновлена, чтобы поддерживать диспетчер VSM, а, следовательно, программирующие на этой платформе получили возможность пользоваться двумя разными средствами (триггерами и диспетчером VSM) для реализации визуальных подсказок. Применение обоих этих средств демонстрируется в рассматриваемых далее примерах.

Построение специального шаблона элемента управления вручную

Прежде чем переходить к рассмотрению различных способов и средств Expression Blend, упрощающих построение специальных шаблонов, покажем, каким образом простой шаблон создается вручную. Ведь лучшего способа, чем этот, для уяснения особенностей создания шаблонов трудно придумать. Когда же вы усвоите эти особенности на примере построения шаблона вручную, вам будет легче создавать другие шаблоны в среде Expression Blend IDE.

Итак, создайте новый проект приложения WPF, присвоив ему имя WpfTemplatesByHand. После этого добавьте одну кнопку (объект типа Button) на монтажном столе в исходном окне типа Window. В настоящий момент кнопка визуализируется с помощью связанного с ней шаблона, используемого по умолчанию. Как упоминалось ранее, этот шаблон является ресурсом, встраиваемым в соответствующую библиотеку на платформе WPF или Silverlight. Определяя свой шаблон, вы по существу, заменяете набор инструкций из используемого по умолчанию шаблона собственным набором инструкций.

Для примера используйте следующий шаблон для кнопки в разметке XAML:

В приведенной выше разметке определен шаблон, состоящий из именованного элемента управления типа Grid, содержащего, в свою очередь, элементы управления типа Ellipse и Label. А поскольку строки или столбцы сетки не определены, то каждый последующий потомок объекта типа Grid располагается над предыдущим, что даёт возможность без труда отцентровать содержимое данного объекта с помощью его свойств VerticalAligment (Выравнивание по вертикали) и HorizontalAligment (Выравнивание по горизонтали). Обратите также внимание на то, что все содержимое злемента разметки присваивается свойству Template элемента управления типа Button в элементе разметки .

Для последующей проверки своего шаблона организуйте на панели Properties обработку события Click, наступающего после щелчка на кнопке, представленной объектом типа Button.

Сохранение шаблонов в виде ресурсов

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

Итак, переместите ресурс локального обыкта типа Button на уровень приложения. Для этого найдите сначала свойство Template данного объекта на панели Properties. Затем откройте меню дополнительных параметров, щелкнув на белом квадратике справа от текстового поля данного свойства. Выберите из этого меню команду Convert to New Resource:

Извлечение шаблона в ресурс

Определите в открывшемся диалоговом окне новый шаблон, сохраняемый под именем RoundButtonTemplate (Шаблон круглой кнопки) в качестве ресурса приложения.

Обратите также внимание на то, что разметка, описывающая исходный объект типа Button, видоизменена. Как показано ниже, в свойстве Template этого объекта ваш шаблон установлен в качестве специального именованного ресурса:

Этот ресурс теперь доступен для всего приложения, а следовательно, в данном приложении можно определить сколько угодно круглых кнопок. Итак, добавьте еще два элемента управления типа Button на монтажном столе исходного окна типа Window. Затем перейдите к панели Properties и установите в свойстве Template каждого из этих элементов управления ресурс RoundButtonTemplate:

Установка специального шаблона Template

Три круглые кнопки, оформленные по единому шаблону

Внедрение визуальных подсказок с помощью триггеров на платформе WPF

Когда вы определяете специальный шаблон, удаляются также все визуальные подсказки, определенные в используемом по умолчанию шаблоне. Напомним, что используемый по умолчанию шаблон содержит инструкции по разметке, в которых уведомляется, каким образом должен выглядеть элемент управления при наступлении в пользовательском интерфейсе определенных событий, например, когда этот элемент получает логический фокус, когда на нем производится щелчок кнопкой мыши, когда он активизируется (или же делается неактивным) и т.д. Пользователи уже привыкли к подобного рода визуальным подсказкам, поскольку они создают хоть какую-то иллюзию реакции элемента пользовательского интерфейса на его касание.

В рассматриваемом здесь шаблоне RoundButtonTemplate подобная разметка не определена, а следовательно, независимо от действий пользователя по отношению к элементу управления, оформляемому по этому шаблону, внешний вид самого элемента изменяется. В идеальном случае внешний вид элемента управления должен хотя бы немного изменяться, когда на нем производится щелчок кнопкой мыши.

Например он может менять свой цвет или уменьшаться в размерах, чтобы дать пользователю наглядно знать о перемене своего состояния.

После первого выпуска платформы WPF для реализации подобных визуальных подсказок в шаблон вводилось любое количество триггеров, которые обычно должны были изменять значения свойств объекта или начинать анимацию по раскадровке либо делать и то и другое, когда становилось истинным условие срабатывания триггера.

В качестве упражнения по реализации подобного подхода на практике обновите шаблон RoundButtonTemplate, как показано в приведенной ниже разметке. После внесения указанных ниже изменений цвет фона элемента управления будет становиться голубым, а цвет переднего плана — желтым при наведении курсора мыши на этот элемент.

Если вы еще раз запустите свое приложение на выполнение, то обнаружите изменение цвета кнопки, когда курсор мыши оказывается в пределах ее границ. Обратите также внимание на то, что данный конкретный элемент определен таким образом, что при установке логического значения true в свойстве IsMouseOver (Курсор мыши наведен) два целевых элемента (buttonSurface и buttonCaption), указываемых в свойстве TargetName (Имя целевого объекта), соответственно изменяют свое состояние.

Приведенная выше разметка не должна вас особенно смущать. Ведь большинство программирующих на платформе WPF согласны с тем, что устанавливать триггеры вручную — занятие малопривлекательное. Поэтому далее будет показано, каким образом панель Triggers используется в Expression Blend для автоматического формирования логики работы триггеров.

Итак, у вас теперь имеется специальный шаблон с несколькими визуальными подсказками, внедренными с помощью триггеров на платформе WPF.

Как скруглить углы у элемента WPF?

Возник вопрос, как закруглять углы элементов? Кнопок, Gryd`ов и т.д.
В целом, весьма распространённая задача, но без поллитра не разобраться.

К слову, насколько хорошая практика, пилить интерфейсы в Blend?

  • Вопрос задан более трёх лет назад
  • 26828 просмотров

Комментировать
Решения вопроса 1

makarenya

программист

Наиболее оптимальный способ — вручную прорисовывать шаблон элемента. Той же кнопки, к примеру.
Первая попавшаяся ссылка с вменяемым по размеру примером:
https://professorweb.ru/my/WPF/Template/level17/17.
Общая суть:
Нужно указать параметр Template у объекта, углы которого скруглять вздумали.
Это можно сделать как в примере на странице через ссылку на StaticResource, либо по месту, указав

Сам шаблон описывается элементом . Ну или не Button, а тот элемент, который вы хотите выдать.
Внутри вы можете нарисовать кнопку так, как вам того хочется. Можно , можно — на ваше усмотрение. Не забываете добавить , чтобы отобразить содержимое кнопки (её текст или любые другие элементы, которые на ней должны размещаться). В реальности вам придётся ещё впоследствии добавить раскраску в зависимости от состояния (активная, курсор наведён, курсор не наведён), и возможно анимацию перехода между этими состояниями!

Чтобы не делать это всё с нуля, часто бывает удобно скопировать стиль по-умолчанию с сайта майкрософт , а потом перкроить его на свой вкус.

Blend так ни разу и не довелось использовать. Всё-таки мне показалось более удобным работать с чистым кодом. Вся идея бленда заключалась на мой взгляд в том, чтобы посадить за него дизайнера, и чтобы последний выдавал на нём готовые для использования блоки. Программеру он ни к чему.

Пошаговое руководство. Создание кнопки с помощью XAML

Это пошаговое руководство предназначено для изучения того, как с помощью XAML можно создать анимированную кнопку для использования в приложении Windows Presentation Foundation. В этом пошаговом руководстве для создания ресурса настраиваемой кнопки используются стили и шаблон, что обеспечивает повторное использование кода и разделение логики кнопки от объявления кнопки. Код в этом пошаговом руководстве полностью написан на языке XAML.

В этом пошаговом руководстве показано, как можно создать приложение путем ввода или копирования и вставки кода на языке XAML в Visual Studio. Если вы хотите узнать, как для создания того же приложения использовать конструктор, см. статью Создание кнопки с помощью Microsoft Expression Blend.

На следующем рисунке показаны готовые кнопки.

Создание основных кнопок

Начнем с создания проекта и добавления нескольких кнопок в окно.

Создание проекта WPF и добавление кнопок в окно

  1. Запустите среду Visual Studio.
  2. Создайте новый проект WPF: в меню Файл нажмите сначала пункт Создать, а затем Проект. Найдите шаблон Приложение Windows (WPF) и назначьте проекту имя «AnimatedButton». В результате будет создана основная структура для приложения.
  3. Добавьте основные кнопки по умолчанию: Все файлы, необходимые для этого пошагового руководства, предоставляются шаблоном. Откройте файл Window1.xaml, дважды щелкнув его в Обозревателе решений. По умолчанию в файле Window1.xaml есть элемент Grid. Удалите элемент Grid и добавьте несколько кнопок на страницу XAML, введя или вставив следующий фрагмент кода в файл Window1.xaml:
        

Задание основных свойств

Давайте настроим некоторые свойств этих кнопок, чтобы осуществить управление их внешним видом и макетом. Вместо того, чтобы настраивать свойства кнопок по отдельности, нужно использовать ресурсы для определения свойств кнопок во всем приложении. Ресурсы приложений концептуально похожи на внешние каскадные таблицы стилей (CSS) для веб-страниц; однако ресурсы намного эффективней каскадных таблицы стилей (CSS), в чем можно будет убедиться в конце этого пошагового руководства. Дополнительные сведения о ресурсах см. в разделе Ресурсы XAML.

Использование стилей для задания основных свойств кнопок

  1. Определите блок Application.Resources: откройте файл app.xaml и добавьте следующий выделенный фрагмент разметки, если он еще отсутствует в этом файле:

Создание шаблона, определяющего внешний вид кнопки

В этом разделе создается шаблон, который настраивает внешний вид (представление) кнопки. Внешний вид кнопки состоит из нескольких объектов, включая прямоугольники и другие компоненты, позволяющие придать кнопке уникальный вид.

До сих пор управление тем, как кнопки выглядят в приложении, ограничивалось изменением свойств кнопки. А что если нужно внести более радикальные изменения во внешний вид кнопки? Шаблоны предоставляют более широкие возможности по управлению внешним видом объекта. Так как шаблоны можно использовать в стилях, шаблоны применимы ко всем объектам, к которым применяется стиль (в этом пошаговом руководстве это кнопка).

Использование шаблона для определения внешнего вида кнопки

  1. Настройте шаблон: вследствие того, что у таких элементов управления, как Button имеется свойство Template, можно определить значение свойства шаблона также, как другие значения свойств, которые задавались ранее в объекте Style с помощью объекта Setter. Добавьте следующий выделенный фрагмент с разметкой в стиль кнопки.
   " RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" /> " RadiusX="20" RadiusY="20" />  " TextBlock.Foreground="Black" />    

Эти ресурсы используются как свойство Fill для прямоугольника, который вставляется в объект Grid из шаблона кнопки. Добавьте в шаблон следующий выделенный фрагмент с разметкой.

                        " TextBlock.Foreground="Black" />    

Создание интерактивности для кнопки

В этом разделе создаются триггеры свойств и триггеры событий, выполняющие изменение значений свойств и запуск анимации в ответ на действия пользователя, такие как перемещение указателя мыши на кнопку и нажатие кнопки.

Простым способом для добавления интерактивности (при наведении указателя мыши, выходе указателя мыши, нажатии кнопки мыши и т. д.) является определение триггеров в шаблоне или стиле. Чтобы создать Trigger, нужно определить условие для свойства, например: значение свойства IsMouseOver у кнопки равняется true . Затем нужно определить методы задания (действия), которые выполняются, когда условие триггера имеет значение «true».

Создание интерактивности для кнопки

  1. Добавьте в шаблон триггеры: добавьте выделенный фрагмент с разметкой в свой шаблон.
 ">                       " TextBlock.Foreground="Black" />   

Итоги

В этом пошаговом руководстве были выполнены следующие практические задания:

  • Создание объекта Style в соответствии с целевым типом объекта (Button).
  • Управление основными свойствами кнопок во всем приложении с помощью объекта Style.
  • Создание таких ресурсов, как градиенты, используемые в соответствии со значениями свойств из методов задания Style.
  • Настройка внешнего вида кнопок во всем приложении путем применения к кнопкам шаблона.
  • Настройка поведения кнопок в ответ на действия пользователя (такие как MouseEnter, MouseLeave и Click) с эффектами анимации.

См. также

  • Создание кнопки с помощью Microsoft Expression Blend
  • Стилизация и использование шаблонов
  • Общие сведения об эффектах анимации
  • Общие сведения о закраске сплошным цветом и градиентом
  • Общие сведения об эффектах для точечных рисунков

Совместная работа с нами на GitHub

Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *