Нашел множество примеров как сделать круглые кнопки, но не одного решения о том как сделать в виде треугольника. Возможно ли это, или лучше использовать изображение для этой цели?
Чтобы кнопка была действительно треугольной, необходимо переопределить ее шаблон.
Чтобы не писать шаблон с нуля полностью, я возьму за основу стандартный, для этого в Visual Studio в дизайнере щелкаем правой по кнопке и выбираем Edit Template-Edit a Copy... и вводим желаемое название шаблона и выбираем место его расположения (можно просто нажать OK и переместить/переименовать позже вручную).
Студия добавит стандартный шаблон кнопки, редактируем его: ищем <Setter Property="Template">
у меня там такой шаблон:
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
В другой ОС он может отличаться, правим его:
<Path Name="border" Stroke="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}" Data="M12,24 L36,0 L36,48 Z" Width="48"/>
Кнопка будет простая и не будет уметь содержать контент, поэтому одного Path
достаточно.
Смотрим теперь те места, что подчеркнуты синим, наименования свойств у Border
и Path
отличаются, поэтому надо эти места поправить, кисть для границы называется Stroke
(вместо BorderBrush
), а кисть для заливки — Fill
(вместо Background
). Контента нет, поэтому строчку <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
удаляю полностью.
Триггеры поправлены, синих подчеркиваний не должно остаться, дизайнер должен заработать, можно запустить и проект. Кнопка, в принципе, уже функционирует нормально, но если с помощью клавиши Tab установить на нее фокус, то мы увидим, что он прямоугольный. За фокус отвечает свойство FocusVisualStyle
, видим в стиле, что он устанавливается так: <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
, т.е. необходимо отредактировать также ресурс FocusVisual
, там сейчас находится Rectangle
, мы возьмем наш уже готовый Path
, но без заливки и с прерывистой границей (как и было у Rectangle
):
<Path Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2" Data="M12,24 L36,0 L36,48 Z" Width="48"/>
Видим, что геометрия Path
повторяется дважды, чтобы избежать дублирования, вынесем ее отдельным ресурсом:
<StreamGeometry x:Key="Geometry">M12,24 L36,0 L36,48 Z</StreamGeometry>
Тогда в Path
достаточно будет указать Data="{StaticResource Geometry}"
Ну и напоследок можно поудалять ненужные сеттеры из стиля, которые касаются контента.
Еще, для того, чтобы иметь возможность получить кнопки со стрелками еще и вниз/вверх/вправо, добавим в ресурсы следующие трансформации:
<RotateTransform x:Key="Rotate90" CenterX="24" CenterY="24" Angle="90"/>
<RotateTransform x:Key="Rotate180" CenterX="24" CenterY="24" Angle="180"/>
<RotateTransform x:Key="Rotate270" CenterX="24" CenterY="24" Angle="270"/>
В итоге весь пример целиком выглядит следующим образом:
<Window.Resources>
<StreamGeometry x:Key="Geometry">M12,24 L36,0 L36,48 Z</StreamGeometry>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Path Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2" Data="{StaticResource Geometry}" Width="48"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<Style x:Key="TriangleButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Path Name="border" Stroke="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}" Data="{StaticResource Geometry}" Width="48"/>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="Stroke" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="Stroke" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Fill" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="Stroke" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="Stroke" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<RotateTransform x:Key="Rotate090" CenterX="24" CenterY="24" Angle="090"/>
<RotateTransform x:Key="Rotate180" CenterX="24" CenterY="24" Angle="180"/>
<RotateTransform x:Key="Rotate270" CenterX="24" CenterY="24" Angle="270"/>
</Window.Resources>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Style="{DynamicResource TriangleButtonStyle}"/>
<Button Style="{DynamicResource TriangleButtonStyle}" RenderTransform="{StaticResource Rotate090}"/>
<Button Style="{DynamicResource TriangleButtonStyle}" RenderTransform="{StaticResource Rotate180}"/>
<Button Style="{DynamicResource TriangleButtonStyle}" RenderTransform="{StaticResource Rotate270}"/>
</StackPanel>
Вам надо просто создать иконку в векторном стиле с помощью Path
и удалить границы и фон с кнопки (для этого стиль кнопки основываем на {StaticResource {x:Static ToolBar.ButtonStyleKey}}
, так как с помощью этого стиля удаляются границы и фон кнопки).
В итоге XAML окна (к примеру, MainWindow.xaml
):
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Style="{StaticResource ArrowButtonStyle}">
<Path Style="{StaticResource ArrowIconButtonStyle}" />
</Button>
<Button Style="{StaticResource ArrowButtonStyle}">
<Path Style="{StaticResource ArrowIconButtonStyle}">
<Path.RenderTransform>
<RotateTransform Angle="90" />
</Path.RenderTransform>
</Path>
</Button>
<Button Style="{StaticResource ArrowButtonStyle}">
<Path Style="{StaticResource ArrowIconButtonStyle}">
<Path.RenderTransform>
<RotateTransform Angle="180" />
</Path.RenderTransform>
</Path>
</Button>
<Button Style="{StaticResource ArrowButtonStyle}">
<Path Style="{StaticResource ArrowIconButtonStyle}">
<Path.RenderTransform>
<RotateTransform Angle="-90" />
</Path.RenderTransform>
</Path>
</Button>
</StackPanel>
Стили (к примеру, в App.xaml
):
<Style x:Key="ArrowButtonStyle" TargetType="Button" BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
<Setter Property="Padding" Value="5" />
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
</Style>
<Style x:Key="ArrowIconButtonStyle" TargetType="Path">
<Setter Property="Data" Value="F1 M 287.328,237.333L 319.344,255.818L 319.344,218.849L 287.328,237.333 Z " />
<Setter Property="Fill" Value="#00a8f3" />
<Setter Property="Width" Value="40" />
<Setter Property="Height" Value="80" />
<Setter Property="Stretch" Value="Fill" />
<Setter Property="RenderTransformOrigin" Value="0.5, 0.5" />
</Style>
В итоге получаем разные стрелки:
Если эти кнопки надо переиспользовать много раз, то можно и свойство RenderTransform
положить в отдельные стили для каждого направления стрелки.
MainWindow.xaml
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Style="{StaticResource ArrowButtonStyle}">
<Path Style="{StaticResource ArrowLeftIconButtonStyle}" />
</Button>
<Button Style="{StaticResource ArrowButtonStyle}">
<Path Style="{StaticResource ArrowTopIconButtonStyle}" />
</Button>
<Button Style="{StaticResource ArrowButtonStyle}">
<Path Style="{StaticResource ArrowRightIconButtonStyle}" />
</Button>
<Button Style="{StaticResource ArrowButtonStyle}">
<Path Style="{StaticResource ArrowBottomIconButtonStyle}" />
</Button>
</StackPanel>
App.xaml
<Style x:Key="ArrowButtonStyle" TargetType="Button" BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
<Setter Property="Padding" Value="5" />
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
</Style>
<Style x:Key="ArrowIconButtonStyle" TargetType="Path">
<Setter Property="Data" Value="F1 M 287.328,237.333L 319.344,255.818L 319.344,218.849L 287.328,237.333 Z " />
<Setter Property="Fill" Value="#00a8f3" />
<Setter Property="Width" Value="40" />
<Setter Property="Height" Value="80" />
<Setter Property="Stretch" Value="Fill" />
<Setter Property="RenderTransformOrigin" Value="0.5, 0.5" />
</Style>
<Style x:Key="ArrowLeftIconButtonStyle" TargetType="Path" BasedOn="{StaticResource ArrowIconButtonStyle}">
</Style>
<Style x:Key="ArrowRightIconButtonStyle" TargetType="Path" BasedOn="{StaticResource ArrowIconButtonStyle}">
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="180" />
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ArrowTopIconButtonStyle" TargetType="Path" BasedOn="{StaticResource ArrowIconButtonStyle}">
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="90" />
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ArrowBottomIconButtonStyle" TargetType="Path" BasedOn="{StaticResource ArrowIconButtonStyle}">
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="-90" />
</Setter.Value>
</Setter>
</Style>
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
C# Консольное приложениеРеализована связка Topshelf+Quartz
В приложении имеется главное окно и множество userControlНа главном окне расположены все кнопки управления (такие как: добавление данных, редактирование...
Надо выводить текущее время на экран, чтобы оно менялось в реальном времениЕдинственный способ реализации, который я вижу — реализация через...
У меня есть модель DealModel в которой есть кастомные свойства по типу CustomInt, CustomDate, CustomDecimal ит