如何将 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,并使用自定义 ControlTemplateKaxaml 中构建了一个原型(我认为这是你追求的行为):

<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 上使用 StrokeThicknessStroke 属性来提供控件的轮廓;在选择按钮之前 Fill 是透明的,然后触发器负责在切换按钮时将 Fill 属性 变为黄色。

分别切换和取消切换。