WPF控件样式和模板全解析-RadioButton控件
RadioButton的默认样式和模板
依旧是使用Blend来查看RadioButton的默认样式和模板
1 <Style x:Key="FocusVisual"> 2 <Setter Property="Control.Template"> 3 <Setter.Value> 4 <ControlTemplate> 5 <Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/> 6 </ControlTemplate> 7 </Setter.Value> 8 </Setter> 9 </Style> 10 <Style x:Key="OptionMarkFocusVisual"> 11 <Setter Property="Control.Template"> 12 <Setter.Value> 13 <ControlTemplate> 14 <Rectangle Margin="14,0,0,0" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/> 15 </ControlTemplate> 16 </Setter.Value> 17 </Setter> 18 </Style> 19 <SolidColorBrush x:Key="RadioButton.Static.Background" Color="#FFFFFFFF"/> 20 <SolidColorBrush x:Key="RadioButton.Static.Border" Color="#FF707070"/> 21 <SolidColorBrush x:Key="RadioButton.Static.Glyph" Color="#FF212121"/> 22 <SolidColorBrush x:Key="RadioButton.MouseOver.Background" Color="#FFF3F9FF"/> 23 <SolidColorBrush x:Key="RadioButton.MouseOver.Border" Color="#FF5593FF"/> 24 <SolidColorBrush x:Key="RadioButton.MouseOver.Glyph" Color="#FF212121"/> 25 <SolidColorBrush x:Key="RadioButton.Pressed.Background" Color="#FFD9ECFF"/> 26 <SolidColorBrush x:Key="RadioButton.Pressed.Border" Color="#FF3C77DD"/> 27 <SolidColorBrush x:Key="RadioButton.Pressed.Glyph" Color="#FF212121"/> 28 <SolidColorBrush x:Key="RadioButton.Disabled.Background" Color="#FFE6E6E6"/> 29 <SolidColorBrush x:Key="RadioButton.Disabled.Border" Color="#FFBCBCBC"/> 30 <SolidColorBrush x:Key="RadioButton.Disabled.Glyph" Color="#FF707070"/> 31 <Style x:Key="RadioButtonStyle1" TargetType="{x:Type RadioButton}"> 32 <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/> 33 <Setter Property="Background" Value="{StaticResource RadioButton.Static.Background}"/> 34 <Setter Property="BorderBrush" Value="{StaticResource RadioButton.Static.Border}"/> 35 <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 36 <Setter Property="BorderThickness" Value="1"/> 37 <Setter Property="Template"> 38 <Setter.Value> 39 <ControlTemplate TargetType="{x:Type RadioButton}"> 40 <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True"> 41 <Grid.ColumnDefinitions> 42 <ColumnDefinition Width="Auto"/> 43 <ColumnDefinition Width="*"/> 44 </Grid.ColumnDefinitions> 45 <Border x:Name="radioButtonBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="100" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1,1,2,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"> 46 <Grid x:Name="markGrid" Margin="2"> 47 <Ellipse x:Name="optionMark" Fill="{StaticResource RadioButton.Static.Glyph}" MinWidth="6" MinHeight="6" Opacity="0"/> 48 </Grid> 49 </Border> 50 <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 51 </Grid> 52 <ControlTemplate.Triggers> 53 <Trigger Property="HasContent" Value="true"> 54 <Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/> 55 <Setter Property="Padding" Value="4,-1,0,0"/> 56 </Trigger> 57 <Trigger Property="IsMouseOver" Value="true"> 58 <Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.MouseOver.Background}"/> 59 <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.MouseOver.Border}"/> 60 <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource RadioButton.MouseOver.Glyph}"/> 61 </Trigger> 62 <Trigger Property="IsEnabled" Value="false"> 63 <Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.Disabled.Background}"/> 64 <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.Disabled.Border}"/> 65 <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource RadioButton.Disabled.Glyph}"/> 66 </Trigger> 67 <Trigger Property="IsPressed" Value="true"> 68 <Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.Pressed.Background}"/> 69 <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.Pressed.Border}"/> 70 <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource RadioButton.Pressed.Glyph}"/> 71 </Trigger> 72 <Trigger Property="IsChecked" Value="true"> 73 <Setter Property="Opacity" TargetName="optionMark" Value="1"/> 74 </Trigger> 75 <Trigger Property="IsChecked" Value="{x:Null}"> 76 <Setter Property="Opacity" TargetName="optionMark" Value="0.56"/> 77 </Trigger> 78 </ControlTemplate.Triggers> 79 </ControlTemplate> 80 </Setter.Value> 81 </Setter> 82 </Style>
拆解RadioButton的样式和模板
1、首先是Tab 键切换控件焦点时看到的虚线焦点框样式,如下所示
1 <Style x:Key="FocusVisual"> 2 <Setter Property="Control.Template"> 3 <Setter.Value> 4 <ControlTemplate> 5 <Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/> 6 </ControlTemplate> 7 </Setter.Value> 8 </Setter> 9 </Style>
2、前面复选框部分的指示器样式(Content为空时才会显示)
1 <Style x:Key="OptionMarkFocusVisual"> 2 <Setter Property="Control.Template"> 3 <Setter.Value> 4 <ControlTemplate> 5 <Rectangle Margin="14,0,0,0" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/> 6 </ControlTemplate> 7 </Setter.Value> 8 </Setter> 9 </Style>
3、然后是资源画刷定义
1 <SolidColorBrush x:Key="RadioButton.Static.Background" Color="#FFFFFFFF"/> 2 <SolidColorBrush x:Key="RadioButton.Static.Border" Color="#FF707070"/> 3 <SolidColorBrush x:Key="RadioButton.Static.Glyph" Color="#FF212121"/> 4 <SolidColorBrush x:Key="RadioButton.MouseOver.Background" Color="#FFF3F9FF"/> 5 <SolidColorBrush x:Key="RadioButton.MouseOver.Border" Color="#FF5593FF"/> 6 <SolidColorBrush x:Key="RadioButton.MouseOver.Glyph" Color="#FF212121"/> 7 <SolidColorBrush x:Key="RadioButton.Pressed.Background" Color="#FFD9ECFF"/> 8 <SolidColorBrush x:Key="RadioButton.Pressed.Border" Color="#FF3C77DD"/> 9 <SolidColorBrush x:Key="RadioButton.Pressed.Glyph" Color="#FF212121"/> 10 <SolidColorBrush x:Key="RadioButton.Disabled.Background" Color="#FFE6E6E6"/> 11 <SolidColorBrush x:Key="RadioButton.Disabled.Border" Color="#FFBCBCBC"/> 12 <SolidColorBrush x:Key="RadioButton.Disabled.Glyph" Color="#FF707070"/>
4、再就是样式属性设置
如果对RadioButton的常用属性不熟悉的小伙伴可以参考以下链接:
https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/controls/radiobutton
1 <Style x:Key="RadioButtonStyle1" TargetType="{x:Type RadioButton}"> 2 <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/> 3 <Setter Property="Background" Value="{StaticResource RadioButton.Static.Background}"/> 4 <Setter Property="BorderBrush" Value="{StaticResource RadioButton.Static.Border}"/> 5 <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 6 <Setter Property="BorderThickness" Value="1"/> 7 </Style>
5、最后就是核心部分,RadioButton的样式模板。
整体来说RadioButton的模板结构和CheckBox类似。
都是通过Grid定义两列,左边显示复选框,右边显示内容。
1 <ControlTemplate TargetType="{x:Type RadioButton}"> 2 <!--外部容器--> 3 <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True"> 4 <!--定义两列--> 5 <Grid.ColumnDefinitions> 6 <ColumnDefinition Width="Auto"/> 7 <ColumnDefinition Width="*"/> 8 </Grid.ColumnDefinitions> 9 <!--左侧复选框的外边框--> 10 <Border x:Name="radioButtonBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="100" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1,1,2,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"> 11 <Grid x:Name="markGrid" Margin="2"> 12 <!--内部的小圆点--> 13 <Ellipse x:Name="optionMark" Fill="{StaticResource RadioButton.Static.Glyph}" MinWidth="6" MinHeight="6" Opacity="0"/> 14 </Grid> 15 </Border> 16 <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 17 </Grid>
显示层级结构如下:

6、模板的触发器部分
1 <ControlTemplate.Triggers> 2 <!--是否设置了内容--> 3 <Trigger Property="HasContent" Value="true"> 4 <!--未设置内容时,启用前面复选框部分的指示器样式--> 5 <Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/> 6 <Setter Property="Padding" Value="4,-1,0,0"/> 7 </Trigger> 8 <!--是否鼠标悬停--> 9 <Trigger Property="IsMouseOver" Value="true"> 10 <Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.MouseOver.Background}"/> 11 <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.MouseOver.Border}"/> 12 <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource RadioButton.MouseOver.Glyph}"/> 13 </Trigger> 14 <!--是否启用--> 15 <Trigger Property="IsEnabled" Value="false"> 16 <Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.Disabled.Background}"/> 17 <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.Disabled.Border}"/> 18 <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource RadioButton.Disabled.Glyph}"/> 19 </Trigger> 20 <!--是否按下--> 21 <Trigger Property="IsPressed" Value="true"> 22 <Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.Pressed.Background}"/> 23 <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource RadioButton.Pressed.Border}"/> 24 <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource RadioButton.Pressed.Glyph}"/> 25 </Trigger> 26 <!--是否选中--> 27 <Trigger Property="IsChecked" Value="true"> 28 <Setter Property="Opacity" TargetName="optionMark" Value="1"/> 29 </Trigger> 30 <!--是否为不确定状态--> 31 <Trigger Property="IsChecked" Value="{x:Null}"> 32 <Setter Property="Opacity" TargetName="optionMark" Value="0.56"/> 33 </Trigger> 34 </ControlTemplate.Triggers>
VisualState
| VisualState 名称 | VisualStateGroup 名称 | Description |
|---|---|---|
| Checked | CheckStates | 选中控件(已选中)。 IsChecked 是 true。 |
| Disabled | CommonStates | 控件已禁用,无法响应用户输入。 |
| Focused | FocusStates | 控件具有键盘焦点,可以接收输入。 |
| Indeterminate | CheckStates | 控件处于不确定状态。 IsThreeState true,IsCheckednull。 |
| InvalidFocused | ValidationStates | 控件存在验证错误,并且具有键盘焦点。 Validation.HasError 是 true。 |
| InvalidUnfocused | ValidationStates | 控件存在验证错误,但没有键盘焦点。 Validation.HasError 是 true。 |
| MouseOver | CommonStates | 鼠标指针位于控件上。 |
| Normal | CommonStates | 控件处于默认的正常状态。 |
| Pressed | CommonStates | 控件由用户交互按下。 |
| Unchecked | CheckStates | 控件未选中。 IsChecked 是 false。 |
| Unfocused | FocusStates | 控件没有键盘焦点。 |
| Valid | ValidationStates | 该控件有效且没有验证错误。 Validation.HasError 是 false。 |
使用Visual State的样式示例
1 <Style x:Key="RadioButtonStyle2" TargetType="{x:Type RadioButton}"> 2 <Setter Property="SnapsToDevicePixels" 3 Value="true" /> 4 <Setter Property="OverridesDefaultStyle" 5 Value="true" /> 6 <Setter Property="FocusVisualStyle" 7 Value="{DynamicResource RadioButtonFocusVisual}" /> 8 <Setter Property="Template"> 9 <Setter.Value> 10 <ControlTemplate TargetType="{x:Type RadioButton}"> 11 <!--保持跟默认模板一致--> 12 <Grid Background="Transparent"> 13 <Grid.ColumnDefinitions> 14 <ColumnDefinition Width="auto"/> 15 <ColumnDefinition/> 16 </Grid.ColumnDefinitions> 17 18 <Grid Width="13" Height="13"> 19 <Ellipse x:Name="Border" StrokeThickness="1"> 20 <Ellipse.Stroke> 21 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 22 <GradientStop Color="{DynamicResource BorderLightColor}" Offset="0" /> 23 <GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1" /> 24 </LinearGradientBrush> 25 </Ellipse.Stroke> 26 <Ellipse.Fill> 27 <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> 28 <LinearGradientBrush.GradientStops> 29 <GradientStopCollection> 30 <GradientStop Color="{DynamicResource ControlLightColor}" /> 31 <GradientStop Color="{DynamicResource ControlMediumColor}" Offset="1.0" /> 32 </GradientStopCollection> 33 </LinearGradientBrush.GradientStops> 34 </LinearGradientBrush> 35 </Ellipse.Fill> 36 </Ellipse> 37 <Ellipse x:Name="CheckMark" Margin="4" Visibility="Collapsed"> 38 <Ellipse.Fill> 39 <SolidColorBrush Color="{DynamicResource GlyphColor}" /> 40 </Ellipse.Fill> 41 </Ellipse> 42 </Grid> 43 <ContentPresenter Margin="4,0,0,0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" RecognizesAccessKey="True" /> 44 <VisualStateManager.VisualStateGroups> 45 <VisualStateGroup x:Name="CommonStates"> 46 <!--正常状态--> 47 <VisualState x:Name="Normal" /> 48 49 <!--鼠标悬停状态--> 50 <VisualState x:Name="MouseOver"> 51 <Storyboard> 52 <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 53 Storyboard.TargetProperty="(Shape.Fill). 54 (GradientBrush.GradientStops)[1].(GradientStop.Color)"> 55 <EasingColorKeyFrame KeyTime="0" 56 Value="{StaticResource ControlMouseOverColor}" /> 57 </ColorAnimationUsingKeyFrames> 58 </Storyboard> 59 </VisualState> 60 61 <!--鼠标按下状态--> 62 <VisualState x:Name="Pressed"> 63 <Storyboard> 64 <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 65 Storyboard.TargetProperty="(Shape.Fill). 66 (GradientBrush.GradientStops)[1].(GradientStop.Color)"> 67 <EasingColorKeyFrame KeyTime="0" 68 Value="{StaticResource ControlPressedColor}" /> 69 </ColorAnimationUsingKeyFrames> 70 </Storyboard> 71 </VisualState> 72 73 <!--禁用状态--> 74 <VisualState x:Name="Disabled"> 75 <Storyboard> 76 <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 77 Storyboard.TargetProperty="(Shape.Fill). 78 (GradientBrush.GradientStops)[1].(GradientStop.Color)"> 79 <EasingColorKeyFrame KeyTime="0" 80 Value="{StaticResource ControlLightColor}" /> 81 </ColorAnimationUsingKeyFrames> 82 <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 83 Storyboard.TargetProperty="(Shape.Stroke). 84 (GradientBrush.GradientStops)[1].(GradientStop.Color)"> 85 <EasingColorKeyFrame KeyTime="0" 86 Value="#40000000" /> 87 </ColorAnimationUsingKeyFrames> 88 <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 89 Storyboard.TargetProperty="(Shape.Stroke). 90 (GradientBrush.GradientStops)[0].(GradientStop.Color)"> 91 <EasingColorKeyFrame KeyTime="0" 92 Value="#40000000" /> 93 </ColorAnimationUsingKeyFrames> 94 </Storyboard> 95 </VisualState> 96 </VisualStateGroup> 97 <VisualStateGroup x:Name="CheckStates"> 98 <!--选中状态--> 99 <VisualState x:Name="Checked"> 100 <Storyboard> 101 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" 102 Storyboard.TargetName="CheckMark"> 103 <DiscreteObjectKeyFrame KeyTime="0" 104 Value="{x:Static Visibility.Visible}" /> 105 </ObjectAnimationUsingKeyFrames> 106 </Storyboard> 107 </VisualState> 108 <!--未选中状态--> 109 <VisualState x:Name="Unchecked" /> 110 <!--不确认状态--> 111 <VisualState x:Name="Indeterminate" /> 112 </VisualStateGroup> 113 </VisualStateManager.VisualStateGroups> 114 </Grid> 115 </ControlTemplate> 116 </Setter.Value> 117 </Setter> 118 </Style>
运行效果

RadioButton样式示例
1 <Style x:Key="WD.DefaultRadioButton" TargetType="{x:Type RadioButton}"> 2 <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/> 3 <Setter Property="Background" Value="{DynamicResource WD.BackgroundBrush}" /> 4 <Setter Property="BorderBrush" Value="{DynamicResource WD.BaseBrush}" /> 5 <Setter Property="Foreground" Value="{DynamicResource WD.PrimaryTextBrush}" /> 6 <Setter Property="BorderThickness" Value="1" /> 7 <Setter Property="Padding" Value="4,0" /> 8 <Setter Property="VerticalAlignment" Value="Center" /> 9 <Setter Property="HorizontalAlignment" Value="Left" /> 10 <Setter Property="Template"> 11 <Setter.Value> 12 <ControlTemplate TargetType="{x:Type RadioButton}"> 13 <!--外部容器--> 14 <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True"> 15 <!--定义两列--> 16 <Grid.ColumnDefinitions> 17 <ColumnDefinition Width="Auto"/> 18 <ColumnDefinition Width="*"/> 19 </Grid.ColumnDefinitions> 20 <!--左侧复选框的外边框--> 21 <Border x:Name="PART_Border" CornerRadius="100" MinWidth="16" MinHeight="16" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"> 22 <Grid Margin="2"> 23 <!--内部的小圆点--> 24 <Ellipse x:Name="PART_Ellipse" MinWidth="6" MinHeight="6" Fill="{DynamicResource WD.WindowTextBrush}" RenderTransformOrigin=".5,.5"> 25 <Ellipse.RenderTransform> 26 <ScaleTransform ScaleX="0" ScaleY="0" /> 27 </Ellipse.RenderTransform> 28 </Ellipse> 29 </Grid> 30 </Border> 31 32 <ContentPresenter Grid.Column="1" x:Name="PART_ContentPresenter" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" Focusable="False" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 33 <VisualStateManager.VisualStateGroups> 34 <VisualStateGroup x:Name="CheckStates"> 35 <VisualState x:Name="Unchecked" /> 36 <VisualState x:Name="Indeterminate" /> 37 <!--选中状态--> 38 <VisualState x:Name="Checked"> 39 <Storyboard> 40 <!--选中时的中心小圆点水平方向的动画--> 41 <DoubleAnimation Storyboard.TargetName="PART_Ellipse" Storyboard.TargetProperty="(Ellipse.RenderTransform).(ScaleTransform.ScaleX)" To=".6" Duration="00:00:.3"> 42 <DoubleAnimation.EasingFunction> 43 <ExponentialEase EasingMode="EaseOut"/> 44 </DoubleAnimation.EasingFunction> 45 </DoubleAnimation> 46 <!--选中时的中心小圆点垂直方向的动画--> 47 <DoubleAnimation Storyboard.TargetName="PART_Ellipse" Storyboard.TargetProperty="(Ellipse.RenderTransform).(ScaleTransform.ScaleY)" To=".6" Duration="00:00:.3"> 48 <DoubleAnimation.EasingFunction> 49 <ExponentialEase EasingMode="EaseOut"/> 50 </DoubleAnimation.EasingFunction> 51 </DoubleAnimation> 52 </Storyboard> 53 </VisualState> 54 </VisualStateGroup> 55 </VisualStateManager.VisualStateGroups> 56 </Grid> 57 <ControlTemplate.Triggers> 58 <!--通过触发器设置选中状态的背景和边框颜色--> 59 <Trigger Property="IsChecked" Value="True"> 60 <Setter TargetName="PART_Border" Property="Background" Value="{DynamicResource WD.PrimaryBrush}" /> 61 <Setter TargetName="PART_Border" Property="BorderBrush" Value="{DynamicResource WD.PrimaryBrush}" /> 62 </Trigger> 63 <MultiTrigger> 64 <!--通过触发器设置未选中并且鼠标悬停时的边框颜色--> 65 <MultiTrigger.Conditions> 66 <Condition Property="IsChecked" Value="False" /> 67 <Condition Property="IsMouseOver" Value="True" /> 68 </MultiTrigger.Conditions> 69 <Setter TargetName="PART_Border" Property="BorderBrush" Value="{DynamicResource WD.PrimaryBrush}" /> 70 </MultiTrigger> 71 </ControlTemplate.Triggers> 72 </ControlTemplate> 73 </Setter.Value> 74 </Setter> 75 </Style>
运行效果

示例代码
https://github.com/zhaotianff/cnblog-demo-code/tree/main/WPFStyleAndTemplateDemo

浙公网安备 33010602011771号