一.前言

  申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接。

本文主要内容:

  • CheckBox复选框的自定义样式,有两种不同的风格实现;
  • RadioButton单选框自定义样式,有两种不同的风格实现;

二. 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#代码:

    /// <summary>
/// BulletCheckBox.xaml 的交互逻辑
/// </summary>
public class BulletCheckBox : CheckBox
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(BulletCheckBox), new PropertyMetadata("Off"));
/// <summary>
/// 默认文本(未选中)
/// </summary>
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
} public static readonly DependencyProperty CheckedTextProperty = DependencyProperty.Register(
"CheckedText", typeof(string), typeof(BulletCheckBox), new PropertyMetadata("On"));
/// <summary>
/// 选中状态文本
/// </summary>
public string CheckedText
{
get { return (string)GetValue(CheckedTextProperty); }
set { SetValue(CheckedTextProperty, value); }
} public static readonly DependencyProperty CheckedForegroundProperty =
DependencyProperty.Register("CheckedForeground", typeof(Brush), typeof(BulletCheckBox), new PropertyMetadata(Brushes.WhiteSmoke));
/// <summary>
/// 选中状态前景样式
/// </summary>
public Brush CheckedForeground
{
get { return (Brush)GetValue(CheckedForegroundProperty); }
set { SetValue(CheckedForegroundProperty, value); }
} public static readonly DependencyProperty CheckedBackgroundProperty =
DependencyProperty.Register("CheckedBackground", typeof(Brush), typeof(BulletCheckBox), new PropertyMetadata(Brushes.LimeGreen));
/// <summary>
/// 选中状态背景色
/// </summary>
public Brush CheckedBackground
{
get { return (Brush)GetValue(CheckedBackgroundProperty); }
set { SetValue(CheckedBackgroundProperty, value); }
} static BulletCheckBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BulletCheckBox), new FrameworkPropertyMetadata(typeof(BulletCheckBox)));
}
}

样式代码,状态变换用了点小动画,为了支持缩放,用了一个Viewbox来包装内容:

    <Style TargetType="{x:Type local:BulletCheckBox}">
<Setter Property="Background" Value="#FF4A9E4A"></Setter>
<Setter Property="Foreground" Value="#DDE8E1"></Setter>
<Setter Property="CheckedForeground" Value="White"></Setter>
<Setter Property="CheckedBackground" Value="#FF0CC50C"></Setter>
<Setter Property="FontSize" Value="13"></Setter>
<Setter Property="Cursor" Value="Hand"></Setter>
<Setter Property="Width" Value="75"></Setter>
<Setter Property="Height" Value="28"></Setter>
<Setter Property="Margin" Value="1"></Setter>
<Setter Property="Template">
<Setter.Value>
<!--控件模板-->
<ControlTemplate TargetType="{x:Type local:BulletCheckBox}">
<Viewbox Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Center">
<Border x:Name="border" Width="75" Height="28" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"
Margin="{TemplateBinding Margin}" CornerRadius="14">
<StackPanel Orientation="Horizontal">
<!--状态球-->
<Border x:Name="state" Width="24" Height="24" Margin="3,2,1,2" CornerRadius="12" SnapsToDevicePixels="True"
Background="{TemplateBinding Foreground}">
<Border.RenderTransform>
<TranslateTransform x:Name="transState" X="0"></TranslateTransform>
</Border.RenderTransform>
</Border>
<!--文本框-->
<TextBlock Width="40" Foreground="{TemplateBinding Foreground}" x:Name="txt" Text="{TemplateBinding Text}" VerticalAlignment="Center" TextAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform x:Name="transTxt" X="0"></TranslateTransform>
</TextBlock.RenderTransform>
</TextBlock>
</StackPanel>
</Border>
</Viewbox> <!--触发器:设置选中状态符号-->
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Text" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedText}" TargetName="txt"/>
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedForeground}" TargetName="state"/>
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedForeground}" TargetName="txt"/>
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CheckedBackground}" TargetName="border"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="transState" Storyboard.TargetProperty="X" To="45" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetName="transTxt" Storyboard.TargetProperty="X" To="-24" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="transState" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetName="transTxt" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger> <Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

使用示例:

            <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自定义控件与样式(2)-自定义按钮FButton

WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

版权所有,文章来源:http://www.cnblogs.com/anding

个人能力有限,本文内容仅供学习、探讨,欢迎指正、交流。

WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式的更多相关文章

  1. 【转】WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等 本文主要内容: CheckBox复选框的自定义样式,有两种不同的风格实现: RadioB ...

  2. [WPF 自定义控件]在MenuItem上使用RadioButton

    1. 需求 上图这种包含多选(CheckBox)和单选(RadioButton)的菜单十分常见,可是在WPF中只提供了多选的MenuItem.顺便一提,要使MenuItem可以多选,只需要将MenuI ...

  3. RadioButton 自定义样式(带动画)

    <Style x:Key="Radbtn" TargetType="{x:Type RadioButton}"> <Setter Proper ...

  4. input type="file"在各个浏览器下的默认样式,以及修改自定义样式

    一.<input type="file"/>在各个浏览器中的默认样式: 系统 浏览器 样式效果 点击效果 mac google 点击按钮和输入框都可以打开文件夹 mac ...

  5. WPF自定义控件与样式(2)-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...

  6. WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控 ...

  7. WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Scr ...

  8. WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Dat ...

  9. WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 下拉选 ...

随机推荐

  1. ruby日记1

    1.irb参数配置 ~/.irbrc IRB.conf[:PROMPT_MODE] = :SIMPLE #简化 irb 提示符,以及禁用一些烦人的自动缩进行为 IRB.conf[:AUTO_INDEN ...

  2. 8.3 网络通信 Volley

    AsyncHttpClient,它把HTTP所有的通信细节全部封装在了内部,我们只需要简单调用几行代码就可以完成通信操作了. Universal-Image-Loader,它使得在界面上显示网络图片的 ...

  3. php 正则

    1.中括号 [0-9]匹配0-9 [a-z]匹配a-z小写字母 [A-Z]匹配A-Z大写字母 [a-zA-Z]匹配所有大小写字母 可以使用ascii来制定更多 2.量词 p+匹配至少一个含p的字符串 ...

  4. Yii2 性能优化 来源yii2官方文档

    优化你的 PHP 环境 使用最新稳定版本的 PHP . PHP 的主要版本可能带来显著的性能提升. 启用字节码缓存 Opcache(PHP 5.5或更高版本) 或 APC (PHP 5.4或更早版本) ...

  5. 视频聊天室可以用php制作吗?

    首先,告诉你单纯用php制作视频聊天室是实现不了的,需要配合其他技术手段一起操作,例如和FLASH配合,使用FLASH获取语音(FLASH可以获取访问端的设备,例如摄像头). PHP运行在服务器端,是 ...

  6. Android性能优化典范第一季

    2015年伊始,Google发布了关于Android性能优化典范的专题,一共16个短视频,每个3-5分钟,帮助开发者创建更快更优秀的Android App.课程专题不仅仅介绍了Android系统中有关 ...

  7. Python札记 -- MongoDB模糊查询

    最近在使用MongoDB的时候,遇到了使用多个关键词进行模糊查询的场景.竹风使用的是mongoengine库. 查了各种资料,最后总结出比较好用的方法.先上代码,后面进行详细说明.如下: #!/usr ...

  8. Xamarin开发IOS笔记:切换输入法时输入框被遮住

    在进行IOS开发的过程中,出现类似微信朋友圈的交互界面,当用户遇到感兴趣的内容可以进行评论.为了方便评论输入,当出现评论输入框的时候自动将评论输入框移动至键盘的上方,这样方便边输入边查看. 当用户隐藏 ...

  9. ENode 2.0 - 第一个真实案例剖析-一个简易论坛(Forum)

    前言 经过不断的坚持和努力,ENode 2.0的第一个真实案例终于出来了.这个案例是一个简易的论坛,开发这个论坛的初衷是为了验证用ENode框架来开发一个真实项目的可行性.目前这个论坛在UI上是使用了 ...

  10. dojo Provider(script、xhr、iframe)源码解析

    总体结构 dojo/request/script.dojo/request/xhr.dojo/request/iframe这三者是dojo提供的provider.dojo将内部的所有provider构 ...