如何将 WPF ToggleButton 样式设置为星形按钮
How to style a WPF ToggleButton like star button
appbar_star
静态资源是star来自modern-icons
的设计
StarToggleButtonStyle
<Style x:Key="StarToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
RecognizesAccessKey="True"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
用法
<ToggleButton cal:Message.Attach="Favorite($dataContext)" Width="15" Height="15" Style="{StaticResource StarToggleButtonStyle}" Margin="10,0,0,0">
<Rectangle Width="10" Height="10" Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ToggleButton}}}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{StaticResource appbar_star}" />
</Rectangle.OpacityMask>
</Rectangle>
</ToggleButton>
但是,这是我从上面的标记中得到的:
我希望边框沿着内容图标,而不是方形边框。如何实现?
我采用了一种略有不同的方法,从您列出的资源中使用 Path
抓取了 Canvas
,并使用自定义 ControlTemplate
在 Kaxaml
中构建了一个原型(我认为这是你追求的行为):
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Background="Coral">
<Grid >
<Grid.Resources>
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Key="AppBar" x:Name="appbar_star" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="41.1667" Height="38" Canvas.Left="17.4167" Canvas.Top="18" Stretch="Fill" Fill="#FF000000" Data="F1 M 17.4167,32.25L 32.9107,32.25L 38,18L 43.0893,32.25L 58.5833,32.25L 45.6798,41.4944L 51.4583,56L 38,48.0833L 26.125,56L 30.5979,41.7104L 17.4167,32.25 Z "/>
</Canvas>
<!-- StarButton Template -->
<ControlTemplate x:Key="StarToggleButton" TargetType="{x:Type ToggleButton}">
<Canvas
Width="76"
Height="76"
Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path
x:Name="ButtonPath"
Width="41.166"
Height="38"
Canvas.Left="17.416"
Canvas.Top="18"
Data="F1 M 17.416,32.25L 32.910,32.25L 38,18L 43.089,32.25L 58.583,32.25L 45.679,41.494L 51.458,56L 38,48.083L 26.125,56L 30.597,41.710L 17.416,32.25 Z "
Fill="Transparent"
Stroke="Black"
StrokeThickness="2"
Stretch="Fill"/>
</Canvas>
<!-- When checked, fill with Yellow -->
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="ButtonPath" Property="Fill" Value="Yellow"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Grid.Resources>
<!-- Example Usage -->
<Grid Background="Transparent">
<StackPanel Height="25" Margin="5" Orientation="Horizontal">
<RadioButton
Content="All"
GroupName="View"
Padding="2"
Template="{DynamicResource StarToggleButton}"/>
<RadioButton
Content="All2"
GroupName="View"
Padding="2"
Template="{DynamicResource StarToggleButton}"/>
</StackPanel>
</Grid>
</Grid>
</Page>
重要的是我们在 Path
上使用 StrokeThickness
和 Stroke
属性来提供控件的轮廓;在选择按钮之前 Fill
是透明的,然后触发器负责在切换按钮时将 Fill
属性 变为黄色。
分别切换和取消切换。
appbar_star
静态资源是star来自modern-icons
StarToggleButtonStyle
<Style x:Key="StarToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
RecognizesAccessKey="True"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
用法
<ToggleButton cal:Message.Attach="Favorite($dataContext)" Width="15" Height="15" Style="{StaticResource StarToggleButtonStyle}" Margin="10,0,0,0">
<Rectangle Width="10" Height="10" Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ToggleButton}}}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{StaticResource appbar_star}" />
</Rectangle.OpacityMask>
</Rectangle>
</ToggleButton>
但是,这是我从上面的标记中得到的:
我希望边框沿着内容图标,而不是方形边框。如何实现?
我采用了一种略有不同的方法,从您列出的资源中使用 Path
抓取了 Canvas
,并使用自定义 ControlTemplate
在 Kaxaml
中构建了一个原型(我认为这是你追求的行为):
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Background="Coral">
<Grid >
<Grid.Resources>
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Key="AppBar" x:Name="appbar_star" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="41.1667" Height="38" Canvas.Left="17.4167" Canvas.Top="18" Stretch="Fill" Fill="#FF000000" Data="F1 M 17.4167,32.25L 32.9107,32.25L 38,18L 43.0893,32.25L 58.5833,32.25L 45.6798,41.4944L 51.4583,56L 38,48.0833L 26.125,56L 30.5979,41.7104L 17.4167,32.25 Z "/>
</Canvas>
<!-- StarButton Template -->
<ControlTemplate x:Key="StarToggleButton" TargetType="{x:Type ToggleButton}">
<Canvas
Width="76"
Height="76"
Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path
x:Name="ButtonPath"
Width="41.166"
Height="38"
Canvas.Left="17.416"
Canvas.Top="18"
Data="F1 M 17.416,32.25L 32.910,32.25L 38,18L 43.089,32.25L 58.583,32.25L 45.679,41.494L 51.458,56L 38,48.083L 26.125,56L 30.597,41.710L 17.416,32.25 Z "
Fill="Transparent"
Stroke="Black"
StrokeThickness="2"
Stretch="Fill"/>
</Canvas>
<!-- When checked, fill with Yellow -->
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="ButtonPath" Property="Fill" Value="Yellow"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Grid.Resources>
<!-- Example Usage -->
<Grid Background="Transparent">
<StackPanel Height="25" Margin="5" Orientation="Horizontal">
<RadioButton
Content="All"
GroupName="View"
Padding="2"
Template="{DynamicResource StarToggleButton}"/>
<RadioButton
Content="All2"
GroupName="View"
Padding="2"
Template="{DynamicResource StarToggleButton}"/>
</StackPanel>
</Grid>
</Grid>
</Page>
重要的是我们在 Path
上使用 StrokeThickness
和 Stroke
属性来提供控件的轮廓;在选择按钮之前 Fill
是透明的,然后触发器负责在切换按钮时将 Fill
属性 变为黄色。
分别切换和取消切换。