如何将WPF ToggleButton样式设置为星形按钮

3

appbar_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>

然而,从上面的标记中得到以下内容: 输入图像描述 我希望边框跟随内容图标,而不是正方形边框。如何实现?

转换后的文本:https://dev59.com/lXI-5IYBdhLWcg3wu7Pv 或者可以使用圆形代替矩形。 - undefined
我不明白...矩形与什么有关?现代图标中的大多数是canvas,因此我使用OpacityMask的矩形来放置图标,并将其设置为ToggleButton的内容。我接受建议。 - undefined
可能我不明白你在说什么。当你提到"边框"时,我猜想它是来自你所提及和讨论的矩形以及可能存在的默认样式。也许我有些困惑,请忽略我的猜测。 - undefined
你是想要视觉效果(轮廓),还是希望可点击区域跟随形状? - undefined
我正在尝试创建一个形状为星星的按钮。就是这样。如果我从StarToggleButtonStyle中移除<Border>,那么我将得到一个形状为星星的按钮,因为我将按钮的内容设置为一个形状为星星的图标。问题是,当ToggleButton未被选中时,我希望星星是透明的,并带有一个边框。当ToggleButton被选中时,我希望星星是填充为黄色的。我知道如何使用触发器来实现这一点,但我无法弄清楚如何显示星星周围的边框。 - undefined
1个回答

3

我采取了稍微不同的方法,使用您提供的资源中的CanvasPath,在Kaxaml中使用自定义的ControlTemplate制作了一个原型(我认为这就是您想要的行为):

<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属性更改为黄色。

Star Toggle Button

分别为切换和未切换状态。

这太棒了。谢谢,但是我该如何绑定按钮的宽度/高度呢?它太大了,我尝试过使用模板绑定Canvas的宽度/高度,但没有成功。 - undefined
你需要将Width / Height的绑定更改为Width="{TemplateBinding Width}"Height="{TemplateBinding Height}"。在ControlTemplate中的Canvas/Path上(我相信只需要在Path上进行此更改)。 - undefined
不好意思,这样做是行不通的。我所做的是将画布包装在<ViewBox>中,并且使用模板绑定了ViewBox的宽度和高度。谢谢。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接