WPF自定义控件04:FlatRadioButton

前面介绍了WPF自定义控件FlatCheckBox的实现,其中的选中状态是用Font Awesome图标字体实现的。本文将介绍一下自定义的单选按钮FlatRadioButton,它与FlatCheckBox实现过程非常类似,但它是单选的,具有相互排斥的特征,同一组的RadioButton只能同时选中一个。下面将详细介绍具体的实现细节。

1 WPF项目结构


     在WPF自定义控件FlatCheckBox这篇文章中,已经介绍了如何创建示例项目,这里基于项目继续进行控件扩展。本质上,FlatRadioButton是继承RadioButton控件,并通过自定义Style实现的Flat UI效果。具体的项目结构如下图所示:

WPF自定义控件04:FlatRadioButton

    其中的Fonts目录下存放各种图标字体文件,Style目录下存放各种控件的UI 样式定义文件,FlatRadioButton.xaml就是FlatRadioButton控件的样式定义文件。

2 WPF FlatRadioButton实现


     首先在Yd.WpfControls项目中添加一个类FlatRadioButton.cs,它继承自RadioButton控件,示例代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Yd.WpfControls
{
    public class FlatRadioButton : RadioButton
    {
        static FlatRadioButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(FlatRadioButton),
               new FrameworkPropertyMetadata(typeof(FlatRadioButton)));
        }
    }
}

     由代码可知,这里并未对相关的属性和事件进行自定义,而是通过继承RadioButton来快速完成FlatRadioButton自定义控件的开发。FlatRadioButton控件的UI样式主要就是依靠FlatRadioButton.xaml文件进行定义的,示例代码如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:Yd.WpfControls"
                    >
    <!--图标字体引入-->
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary  Source="/Yd.WpfControls;component/Style/IconFont.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <!--FlatRadioButon 样式-->
    <Style TargetType="{x:Type local:FlatRadioButton}">
        <Setter Property="Background" Value="Transparent"></Setter>
        <Setter Property="Foreground" Value="{x:Static local:FlatColors.PETER_RIVER}"></Setter>
        <Setter Property="Padding" Value="0"></Setter>
        <Setter Property="FontSize" Value="{StaticResource FontSize}"></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:FlatRadioButton}">
                    <Grid x:Name="grid" Margin="{TemplateBinding Padding}" VerticalAlignment="Center">
                        <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                            <TextBlock x:Name="icon" Text="&#xf10c;" Style="{StaticResource faFont}" SnapsToDevicePixels="True"
                                       FontSize="26"
                                       Margin="3"
                                       Foreground="{TemplateBinding Foreground}"/>
                            <ContentPresenter VerticalAlignment="Center"/>
                        </StackPanel>
                    </Grid>
                    <!--触发器-->
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="true">
                            <Setter Property="Text" Value="&#xf192;" TargetName="icon" ></Setter>
                            <Setter Property="Foreground" Value="{x:Static local:FlatColors.BELIZE_HOLE}"></Setter>
                        </Trigger>
                        <Trigger Property="IsChecked" Value="{x:Null}">
                            <Setter Property="Text" Value="&#xf10c;" TargetName="icon" ></Setter>
                            <Setter Property="Foreground" Value="{x:Static local:FlatColors.PETER_RIVER}"></Setter>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Foreground" Value="{x:Static local:FlatColors.PETER_RIVER}"></Setter>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Opacity" Value="0.5" TargetName="grid" ></Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

其中的<TextBlock  x:Name="icon" Text="&#xf10c;" Style="{StaticResource faFont}" />则指定了文本的样式定义,Style资源Key为faFont,Text为"&#xf10c;" ,这里需要查看Font Awesome图标字体CheatSheet图标对照清单 ( http://www.fontawesome.com.cn/cheatsheet/),部分界面截图如下:

WPF自定义控件04:FlatRadioButton

通过触发器Trigger来确定FlatRadioButton属性IsChecked变化时,如何在UI上进行显示,比如当选中时,属性IsChecked的值为true时,则会触发如下触发器定义的规则:

<Trigger Property="IsChecked" Value="true">
        <Setter Property="Text" Value="&#xf192;" TargetName="icon" ></Setter>
        <Setter Property="Foreground" Value="{x:Static local:FlatColors.BELIZE_HOLE}"></Setter>
</Trigger>

此时,设置模板中的名称为icon的控件Text值为&#xf192;即为选中的图标,且字体颜色为FlatColors.BELIZE_HOLE 。

3 WPF FlatCheckBox测试


     首先,需要重新生成一下项目文件,然后在WpfControls项目中添加自定义控件FlatRadioButton,MainWindow.xaml部分示例代码如下:

<WpfControls:FlatRadioButton GroupName="EmpType"  Content="MVP" 
                HorizontalAlignment="Left" Margin="62,148,0,0" VerticalAlignment="Top"/>
<WpfControls:FlatRadioButton GroupName="EmpType" Content="VIP" 
                HorizontalAlignment="Left" Margin="62,0,0,0" VerticalAlignment="Center"/>

<WpfControls:FlatRadioButton GroupName="EmpType2"  Content="M" 
                HorizontalAlignment="Left" Margin="355,200,0,178" 
                Foreground="Coral" Width="59"/>
<WpfControls:FlatRadioButton GroupName="EmpType2" Content="F" 
                HorizontalAlignment="Left" Margin="355,127,0,255"  
                Foreground="Coral" Width="59"/>

运行界面如下:

WPF自定义控件04:FlatRadioButton

上一篇:iOS多线程GCD


下一篇:经典的JAVA面试题