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>

 

显示层级结构如下:

image

 

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

 

运行效果

demo

 

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>

 

运行效果

demo

 

示例代码

https://github.com/zhaotianff/cnblog-demo-code/tree/main/WPFStyleAndTemplateDemo

posted @ 2026-09-08 11:46  zhaotianff  阅读(18)  评论(0)    收藏  举报