WPF RadioButton/ToggleButton 样式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18390528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:54:55  来源:igfitidea点击:

WPF RadioButton/ToggleButton styling

wpfstylesradio-buttontogglebutton

提问by Nuts

I would like to mimic a style for a group of ToggleButtons as in the below image. Only one of the buttons can be "Checked" at any time.

我想模仿一组 ToggleButtons 的样式,如下图所示。任何时候都只能“检查”其中一个按钮。

enter image description here

在此处输入图片说明

My question is related to styling:

我的问题与样式有关:

  • I'd like to have rounded corners on the leftmost button and the rightmost button as in the image but if there is a button between (like in the image), that should not have rounded corners. Sometimes there might only be two buttons to toggle.
  • I need style for different states: "Normal/Unchecked", "Mouseover", "Pressed" and "Checked" at the minimum.
  • 我想在最左边的按钮和最右边的按钮上有圆角,如图所示,但如果中间有一个按钮(如图所示),则不应有圆角。有时可能只有两个按钮可以切换。
  • 我需要不同状态的样式:至少“正常/未选中”、“鼠标悬停”、“按下”和“选中”。

The current control I am using for this is done like this:

我为此使用的当前控件是这样完成的:

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

In the StackPanel Resources I am trying to set Style for ToggleButton but I'm pretty lost how to achieve the result as in the image above.

在 StackPanel 资源中,我试图为 ToggleButton 设置样式,但我非常不知道如何实现如上图所示的结果。

回答by Chris

This may not be the easiest/best approach, but I took a stab at knocking up some ControlTemplatesusing Kaxaml, to produce something that looks like this:

这可能不是最简单/最好的方法,但我尝试ControlTemplates使用 Kaxaml 敲掉一些,以生成如下所示的内容:

Button Preview

按钮预览

You could store these templates in a ResourceDictionaryand apply them when required, or use them if you were building your button list on the fly.

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

I actually created three slightly different styles, one for the left and right buttons, and one for the middle (you may be able to simplify this with extending/inheriting styles). Some repeated code omitted.

我实际上创建了三种稍微不同的样式,一种用于左右按钮,一种用于中间(您可以通过扩展/继承样式来简化这一点)。省略了一些重复的代码。

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

You would have to add additional Triggersetc. for the IsPressedstate, and any others required (e.g IsEnabled).

您必须TriggersIsPressed状态添加额外的等,以及任何其他需要的(例如IsEnabled)。