一.前言
申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接。
本文主要内容:
二. CheckBox自定义样式
2.1 CheckBox基本样式
标准CheckBox样式代码如下,实现了三态的显示,其中不同状态的图标用了字体图标(关于字体图标,可以参考本文末尾附录链接)
<Style x:Key="DefaultCheckBox" TargetType="{x:Type CheckBox}"> <Setter Property="Background" Value="Transparent"></Setter> <Setter Property="Foreground" Value="{StaticResource TextForeground}"></Setter> <Setter Property="Padding" Value="0"></Setter> <Setter Property="local:ControlAttachProperty.FIconMargin" Value="1, 1, 3, 1"></Setter> <Setter Property="local:ControlAttachProperty.FIconSize" Value="22"></Setter> <Setter Property="FontSize" Value="{StaticResource FontSize}"></Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type CheckBox}"> <Grid x:Name="grid" Margin="{TemplateBinding Padding}" VerticalAlignment="Center"> <StackPanel Orientation="Horizontal" VerticalAlignment="Center"> <TextBlock x:Name="icon" Style="{StaticResource FIcon}" Text="" FontSize="{TemplateBinding local:ControlAttachProperty.FIconSize}" Margin="{TemplateBinding local:ControlAttachProperty.FIconMargin}" Foreground="{TemplateBinding Foreground}"/> <ContentPresenter VerticalAlignment="Center"/> </StackPanel> </Grid> <!--触发器:设置选中状态符号--> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="true"> <Setter Property="Text" Value="" TargetName="icon" ></Setter> <Setter Property="Foreground" Value="{StaticResource CheckedForeground}"></Setter> </Trigger> <Trigger Property="IsChecked" Value="{x:Null}"> <Setter Property="Text" Value="" TargetName="icon" ></Setter> </Trigger> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Foreground" Value="{StaticResource MouseOverForeground}"></Setter> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="grid" ></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
使用示例及效果:
<CheckBox Margin="3">男</CheckBox> <CheckBox Margin="3">女</CheckBox> <CheckBox Margin="3" IsChecked="{x:Null}">其他</CheckBox> <CheckBox Margin="3" IsChecked="{x:Null}">女</CheckBox> <CheckBox Margin="3" IsEnabled="False">我被禁用了</CheckBox> <CheckBox Margin="3" IsEnabled="False" IsChecked="{x:Null}">我被禁用了</CheckBox> <CheckBox Margin="3" IsEnabled="False" IsChecked="True">我被禁用了</CheckBox>
2.2 CheckBox另一种样式
在移动端比较常见的一种复选效果,先看看效果
这个代码是很久以前写的,用的控件的形式实现的,可以纯样式实现,更简洁,懒得改了。C#代码:
样式代码,状态变换用了点小动画,为了支持缩放,用了一个Viewbox来包装内容:
使用示例:
<kc:BulletCheckBox /> <kc:BulletCheckBox Text="不开窍" CheckedText="开启" IsChecked="True" /> <kc:BulletCheckBox Text="不开窍" CheckedText="开启" IsChecked="True" Height="24" Width="60" /> <kc:BulletCheckBox Height="24" Width="60"/>
三.RadioButton自定义样式
3.1 RadioButon基本样式
标准单选控件的样式很简单,用不同图标标识不同状态,然后触发器控制不同状态的显示效果。
<!--默认样式--> <Style x:Key="DefaultRadioButton" TargetType="{x:Type RadioButton}"> <Setter Property="Background" Value="Transparent"></Setter> <Setter Property="Foreground" Value="{StaticResource TextForeground}"></Setter> <Setter Property="Padding" Value="0"></Setter> <Setter Property="local:ControlAttachProperty.FIconMargin" Value="1, 1, 3, 1"></Setter> <Setter Property="local:ControlAttachProperty.FIconSize" Value="25"></Setter> <Setter Property="FontSize" Value="{StaticResource FontSize}"></Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RadioButton}"> <Grid x:Name="grid" Margin="{TemplateBinding Padding}" VerticalAlignment="Center"> <StackPanel Orientation="Horizontal" VerticalAlignment="Center"> <TextBlock x:Name="icon" Text="" Style="{StaticResource FIcon}" SnapsToDevicePixels="True" FontSize="{TemplateBinding local:ControlAttachProperty.FIconSize}" Margin="{TemplateBinding local:ControlAttachProperty.FIconMargin}" Foreground="{TemplateBinding Foreground}"/> <ContentPresenter VerticalAlignment="Center"/> </StackPanel> </Grid> <!--触发器:设置选中状态符号--> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="true"> <Setter Property="Text" Value="" TargetName="icon" ></Setter> <Setter Property="Foreground" Value="{StaticResource CheckedForeground}"></Setter> </Trigger> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Foreground" Value="{StaticResource MouseOverForeground}"></Setter> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="grid" ></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
使用示例:
<RadioButton Margin="3" core:ControlAttachProperty.FIconSize="18">男</RadioButton> <RadioButton Margin="3" core:ControlAttachProperty.FIconSize="20">女</RadioButton> <RadioButton Margin="3" IsChecked="{x:Null}" core:ControlAttachProperty.FIconSize="22">其他</RadioButton> <RadioButton Margin="3" IsChecked="{x:Null}" core:ControlAttachProperty.FIconSize="24">女</RadioButton> <RadioButton Margin="3" IsChecked="{x:Null}" core:ControlAttachProperty.FIconSize="26">女</RadioButton> <RadioButton Margin="3" IsEnabled="False">我被禁用了</RadioButton> <RadioButton Margin="3" IsEnabled="False" IsChecked="{x:Null}">我被禁用了</RadioButton>
效果图:
3.2 RadioButton淘宝、京东物品尺码单项样式
先看看效果:
样式定义也很简单,右下角那个小勾勾用的是一个字体图标,可以根据需要调整大小。
<Style x:Key="BoxRadioButton" TargetType="{x:Type RadioButton}"> <Setter Property="Background" Value="Transparent"></Setter> <Setter Property="Foreground" Value="{StaticResource TextForeground}"></Setter> <Setter Property="Padding" Value="3 2 3 2"></Setter> <Setter Property="FontSize" Value="{StaticResource FontSize}"></Setter> <Setter Property="BorderThickness" Value="2"></Setter> <Setter Property="Height" Value="auto"></Setter> <Setter Property="SnapsToDevicePixels" Value="true"></Setter> <Setter Property="BorderBrush" Value="{StaticResource ControlBorderBrush}" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RadioButton}"> <Grid x:Name="grid" VerticalAlignment="Center"> <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Height="{TemplateBinding Height}" HorizontalAlignment="Center" Background="{TemplateBinding Background}" Width="{TemplateBinding Width}"> <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Border> <!--选中的状态标识--> <TextBlock Text="" x:Name="checkState" Style="{StaticResource FIcon}" VerticalAlignment="Bottom" Visibility="Collapsed" FontSize="14" Margin="1" HorizontalAlignment="Right" Foreground="{StaticResource CheckedForeground}"/> </Grid> <!--触发器:设置选中状态符号--> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="true"> <Setter Property="Visibility" Value="Visible" TargetName="checkState" ></Setter> <Setter Property="BorderBrush" Value="{StaticResource CheckedForeground}"></Setter> </Trigger> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="BorderBrush" Value="{StaticResource MouseOverForeground}"></Setter> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="grid" ></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
示例代码:
<RadioButton Style="{StaticResource BoxRadioButton}" Margin="1">近3天</RadioButton><RadioButton Style="{StaticResource BoxRadioButton}" Margin="1">近7天</RadioButton><RadioButton Style="{StaticResource BoxRadioButton}" Margin="1">本月</RadioButton><RadioButton Style="{StaticResource BoxRadioButton}" Margin="1">自定义</RadioButton><RadioButton Style="{StaticResource BoxRadioButton}" Margin="1">2012.05.12-2015.12.14</RadioButton>
补充说明,上面样式中有用到附加属性,如
ControlAttachProperty.FIconMargin" Value="1, 1, 3, 1":复选框或单选框字体图标的边距
ControlAttachProperty.FIconSize" Value="25":复选框或单选框字体图标的大小
关于附加属性可以参考上一篇(本文末尾链接),C#定义代码:
#region FIconProperty 字体图标 /// <summary> /// 字体图标 /// </summary> public static readonly DependencyProperty FIconProperty = DependencyProperty.RegisterAttached( "FIcon", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata("")); public static string GetFIcon(DependencyObject d) { return (string)d.GetValue(FIconProperty); } public static void SetFIcon(DependencyObject obj, string value) { obj.SetValue(FIconProperty, value); } #endregion #region FIconSizeProperty 字体图标大小 /// <summary> /// 字体图标 /// </summary> public static readonly DependencyProperty FIconSizeProperty = DependencyProperty.RegisterAttached( "FIconSize", typeof(double), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(12D)); public static double GetFIconSize(DependencyObject d) { return (double)d.GetValue(FIconSizeProperty); } public static void SetFIconSize(DependencyObject obj, double value) { obj.SetValue(FIconSizeProperty, value); } #endregion #region FIconMarginProperty 字体图标边距 /// <summary> /// 字体图标 /// </summary> public static readonly DependencyProperty FIconMarginProperty = DependencyProperty.RegisterAttached( "FIconMargin", typeof(Thickness), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null)); public static Thickness GetFIconMargin(DependencyObject d) { return (Thickness)d.GetValue(FIconMarginProperty); } public static void SetFIconMargin(DependencyObject obj, Thickness value) { obj.SetValue(FIconMarginProperty, value); } #endregion
附录:参考引用
WPF自定义控件与样式(1)-矢量字体图标(iconfont)
WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
联系客服