前面介绍了WPF自定义控件FlatCheckBox的实现,其中的选中状态是用Font Awesome图标字体实现的。本文将介绍一下自定义的单选按钮FlatRadioButton,它与FlatCheckBox实现过程非常类似,但它是单选的,具有相互排斥的特征,同一组的RadioButton只能同时选中一个。下面将详细介绍具体的实现细节。
1 WPF项目结构
在WPF自定义控件FlatCheckBox这篇文章中,已经介绍了如何创建示例项目,这里基于项目继续进行控件扩展。本质上,FlatRadioButton是继承RadioButton控件,并通过自定义Style实现的Flat UI效果。具体的项目结构如下图所示:
其中的Fonts目录下存放各种图标字体文件,Style目录下存放各种控件的UI 样式定义文件,FlatRadioButton.xaml就是FlatRadioButton控件的样式定义文件。
2 WPF FlatRadioButton实现
首先在Yd.WpfControls项目中添加一个类FlatRadioButton.cs,它继承自RadioButton控件,示例代码如下:
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; usingSystem.Windows; usingSystem.Windows.Controls; usingSystem.Windows.Media; namespaceYd.WpfControls{ publicclassFlatRadioButton : RadioButton { staticFlatRadioButton() { DefaultStyleKeyProperty.OverrideMetadata(typeof(FlatRadioButton), newFrameworkPropertyMetadata(typeof(FlatRadioButton))); } } }
由代码可知,这里并未对相关的属性和事件进行自定义,而是通过继承RadioButton来快速完成FlatRadioButton自定义控件的开发。FlatRadioButton控件的UI样式主要就是依靠FlatRadioButton.xaml文件进行定义的,示例代码如下:
<ResourceDictionaryxmlns="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><ResourceDictionarySource="/Yd.WpfControls;component/Style/IconFont.xaml"/></ResourceDictionary.MergedDictionaries><!--FlatRadioButon 样式--><StyleTargetType="{x:Type local:FlatRadioButton}"><SetterProperty="Background"Value="Transparent"></Setter><SetterProperty="Foreground"Value="{x:Static local:FlatColors.PETER_RIVER}"></Setter><SetterProperty="Padding"Value="0"></Setter><SetterProperty="FontSize"Value="{StaticResource FontSize}"></Setter><SetterProperty="Template"><Setter.Value><ControlTemplateTargetType="{x:Type local:FlatRadioButton}"><Gridx:Name="grid"Margin="{TemplateBinding Padding}"VerticalAlignment="Center"><StackPanelOrientation="Horizontal"VerticalAlignment="Center"><TextBlockx:Name="icon"Text=""Style="{StaticResource faFont}"SnapsToDevicePixels="True"FontSize="26"Margin="3"Foreground="{TemplateBinding Foreground}"/><ContentPresenterVerticalAlignment="Center"/></StackPanel></Grid><!--触发器--><ControlTemplate.Triggers><TriggerProperty="IsChecked"Value="true"><SetterProperty="Text"Value=""TargetName="icon"></Setter><SetterProperty="Foreground"Value="{x:Static local:FlatColors.BELIZE_HOLE}"></Setter></Trigger><TriggerProperty="IsChecked"Value="{x:Null}"><SetterProperty="Text"Value=""TargetName="icon"></Setter><SetterProperty="Foreground"Value="{x:Static local:FlatColors.PETER_RIVER}"></Setter></Trigger><TriggerProperty="IsMouseOver"Value="true"><SetterProperty="Foreground"Value="{x:Static local:FlatColors.PETER_RIVER}"></Setter></Trigger><TriggerProperty="IsEnabled"Value="False"><SetterProperty="Opacity"Value="0.5"TargetName="grid"></Setter></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style></ResourceDictionary>
其中的<TextBlock x:Name="icon" Text="" Style="{StaticResource faFont}" />则指定了文本的样式定义,Style资源Key为faFont,Text为"" ,这里需要查看Font Awesome图标字体CheatSheet图标对照清单 ( http://www.fontawesome.com.cn/cheatsheet/),部分界面截图如下:
通过触发器Trigger来确定FlatRadioButton属性IsChecked变化时,如何在UI上进行显示,比如当选中时,属性IsChecked的值为true时,则会触发如下触发器定义的规则:
<TriggerProperty="IsChecked"Value="true"><SetterProperty="Text"Value=""TargetName="icon"></Setter><SetterProperty="Foreground"Value="{x:Static local:FlatColors.BELIZE_HOLE}"></Setter></Trigger>
此时,设置模板中的名称为icon的控件Text值为即为选中的图标,且字体颜色为FlatColors.BELIZE_HOLE 。
3 WPF FlatCheckBox测试
首先,需要重新生成一下项目文件,然后在WpfControls项目中添加自定义控件FlatRadioButton,MainWindow.xaml部分示例代码如下:
<WpfControls:FlatRadioButtonGroupName="EmpType"Content="MVP"HorizontalAlignment="Left"Margin="62,148,0,0"VerticalAlignment="Top"/><WpfControls:FlatRadioButtonGroupName="EmpType"Content="VIP"HorizontalAlignment="Left"Margin="62,0,0,0"VerticalAlignment="Center"/><WpfControls:FlatRadioButtonGroupName="EmpType2"Content="M"HorizontalAlignment="Left"Margin="355,200,0,178"Foreground="Coral"Width="59"/><WpfControls:FlatRadioButtonGroupName="EmpType2"Content="F"HorizontalAlignment="Left"Margin="355,127,0,255"Foreground="Coral"Width="59"/>
运行界面如下: