WPF单选按钮/切换按钮样式设计

14

我想要模仿下面图片中一组ToggleButtons的样式。在任何时候只有一个按钮可以处于“已选”状态。

enter image description here

我的问题与样式相关:

  • 我想要左侧和右侧的按钮拥有圆角,就像图片中所示,但如果中间有一个按钮(如图片中所示),那么它就不应该有圆角。有时可能只有两个切换按钮。
  • 我需要为不同状态提供样式:“正常/未选中”,“鼠标悬停”,“按下”和“已选中”至少。

我目前使用的控件是这样做的:

<StackPanel Orientation="Horizontal" >
    <RadioButton Style="{StaticResource {x:Type ToggleButton}}" Content="All" Padding="12,8,12,8" GroupName="View"  />
    <RadioButton Style="{StaticResource {x:Type ToggleButton}}" Content="Geolocated" Padding="12,8,12,8" GroupName="View" />
    <RadioButton Style="{StaticResource {x:Type ToggleButton}}" Content="Non Geolocated" Padding="12,8,12,8" GroupName="View" />
</StackPanel>

在 StackPanel 资源中,我正在尝试为 ToggleButton 设置样式,但我不太清楚如何实现上面图片中的结果。

1个回答

21

这可能不是最简单/最好的方法,但我尝试使用Kaxaml设计了一些ControlTemplates,制作出类似以下图片的效果:

Button Preview

你可以将这些模板存储在ResourceDictionary中,需要时应用它们,或者在构建按钮列表时使用它们。

我实际上创建了三种略有不同的样式,一个用于左右按钮,一个用于中间(你可能可以通过扩展/继承样式来简化这个过程)。省略了部分重复的代码。

<Grid>
    <Grid.Resources>
        <!-- Brushes for colours/backgrounds -->
        <SolidColorBrush x:Key="FontBrush" Color="#DDDDDD"/>

        <LinearGradientBrush x:Key="BgBrush1" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Offset="0" Color="#888888"/>
            <GradientStop Offset="1" Color="#222222"/>
        </LinearGradientBrush>

        <SolidColorBrush x:Key="BorderBrush1" Color="#333333"/>
        <LinearGradientBrush x:Key="CheckedBrush" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Offset="0" Color="#555555"/>
            <GradientStop Offset="1" Color="#111111"/>
        </LinearGradientBrush>

        <!-- Left Button Template -->
        <ControlTemplate x:Key="ToggleButtonLeft" TargetType="{x:Type ToggleButton}">
            <Border
                Name="Border"
                Background="{StaticResource BgBrush1}"
                BorderBrush="{StaticResource BorderBrush1}"
                BorderThickness="1"
                CornerRadius="5,0,0,5">
                <ContentPresenter
                    HorizontalAlignment="Center"
                    Margin="{TemplateBinding Padding}"
                    VerticalAlignment="Center"
                    Content="{TemplateBinding Content}"
                    TextBlock.FontWeight="Bold"
                    TextBlock.Foreground="{StaticResource FontBrush}"/>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="ToggleButton.IsMouseOver" Value="true">
                    <Setter TargetName="Border" Property="Background" Value="#808080"/>
                </Trigger>
                <Trigger Property="IsChecked" Value="true">
                    <Setter TargetName="Border" Property="Background" Value="{StaticResource CheckedBrush}"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

        <!-- Middle Button(s) Template -->
        <ControlTemplate x:Key="ToggleButtonMid" TargetType="{x:Type ToggleButton}">
            <Border
                Name="Border"
                Background="{StaticResource BgBrush1}"
                BorderBrush="{StaticResource BorderBrush1}"
                BorderThickness="0,1,0,1"
                CornerRadius="0" />
        <!-- Other code identical to Left Button Template -->       
        </ControlTemplate>

        <!-- Right Button Template -->
        <ControlTemplate x:Key="ToggleButtonRight" TargetType="{x:Type ToggleButton}">
            <Border
                Name="Border"
                Background="{StaticResource BgBrush1}"
                BorderBrush="{StaticResource BorderBrush1}"
                BorderThickness="1"
                CornerRadius="0, 5, 5, 0" />
        <!-- Other code identical to Left Button Template -->  
        </ControlTemplate>
    </Grid.Resources>

    <!-- Example Usage -->
    <Grid Background="#555555">
        <StackPanel Height="25" Orientation="Horizontal" Margin="5">
            <RadioButton Content="All" GroupName="View" Padding="2" Template="{DynamicResource ToggleButtonLeft}"/>
            <RadioButton Content="Geolocated" GroupName="View" Padding="2" Template="{DynamicResource ToggleButtonMid}"/>
            <RadioButton Content="Non Geolocated" GroupName="View" Padding="2" Template="{DynamicResource ToggleButtonRight}"/>
        </StackPanel>
    </Grid>
</Grid>

你需要为 IsPressed 状态添加额外的 Triggers,以及任何其他所需的状态(例如IsEnabled)。


1
这段示例代码非常漂亮且有用,谢谢。 - KeyvanSFX
很高兴它经过了这么长时间仍然有用! - Chris

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