WPF自定义控件06:FlatComboBox

简介: 在不少的应用程序中,经常需要使用下拉框(ComboBox)控件来从类别字段中选择,这样可以限定值的范围,让数据更加的规范,便于统计和分析。本文将介绍一下自定义的下拉框控件FlatComboBox,它与FlatCheckBox实现过程非常类似,它是继承自ComboBox,但使用自定义的UI样式来美化界面。下面将详细介绍具体的实现细节。

      在不少的应用程序中,经常需要使用下拉框(ComboBox)控件来从类别字段中选择,这样可以限定值的范围,让数据更加的规范,便于统计和分析。本文将介绍一下自定义的下拉框控件FlatComboBox,它与FlatCheckBox实现过程非常类似,它是继承自ComboBox,但使用自定义的UI样式来美化界面。下面将详细介绍具体的实现细节。

1 WPF项目结构


    基于之前创建的WPF示例项目,在其中创建一个新的关于FlatComboBox的项目文件。本质上,FlatComboBox是继承ComboBox控件,利用ComboBox控件自身的属性和方法,可以减少FlatComboBox实现的难度和复杂度。首先,给出本项目文件结构,如下图所示:

1.jpg

  其中的Fonts目录下存放各种图标字体文件,Style目录下存放各种控件的UI 样式定义文件,FlatComboBox.xaml就是FlatComboBox控件的样式定义文件。另外,需要将其注册到Generic.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"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatButton.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatCheckBox.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatRadioButton.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/ToggleButton.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatComboBox.xaml"/></ResourceDictionary.MergedDictionaries>

2 WPF FlatComboBox实现


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

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Media;
namespaceYd.WpfControls{
publicclassFlatComboBox : ComboBox    {
staticFlatComboBox()
        {
DefaultStyleKeyProperty.OverrideMetadata(typeof(FlatComboBox),
newFrameworkPropertyMetadata(typeof(FlatComboBox)));
        }
    }
}

FlatComboBox控件的UI样式主要就是依靠FlatComboBox.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><!-- Flat ComboBox --><SolidColorBrushx:Key="ComboBoxNormalBorderBrush"Color="#e3e9ef"/><SolidColorBrushx:Key="ComboBoxNormalBackgroundBrush"Color="#fff"/><SolidColorBrushx:Key="ComboBoxDisabledForegroundBrush"Color="#999"/><SolidColorBrushx:Key="ComboBoxDisabledBorderBrush"Color="#999"/><SolidColorBrushx:Key="ComboBoxDisabledBackgroundBrush"Color="#eee"/><Stylex:Key="{x:Type ComboBoxItem}"TargetType="{x:Type ComboBoxItem}"><SetterProperty="SnapsToDevicePixels"Value="True"/><SetterProperty="OverridesDefaultStyle"Value="True"/><SetterProperty="Template"><Setter.Value><ControlTemplateTargetType="{x:Type ComboBoxItem}"><Borderx:Name="Border"Padding="1"SnapsToDevicePixels="True"Background="Transparent"><VisualStateManager.VisualStateGroups><VisualStateGroupx:Name="SelectionStates"><VisualStatex:Name="Unselected"/><VisualStatex:Name="Selected"><Storyboard><ColorAnimationUsingKeyFramesStoryboard.TargetName="Border"Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"><EasingColorKeyFrameKeyTime="0"Value="#BDC3C7"/></ColorAnimationUsingKeyFrames></Storyboard></VisualState><VisualStatex:Name="SelectedUnfocused"><Storyboard><ColorAnimationUsingKeyFramesStoryboard.TargetName="Border"Storyboard.TargetProperty="(Panel.Background). (SolidColorBrush.Color)"><EasingColorKeyFrameKeyTime="0"Value="#e3e9ef"/></ColorAnimationUsingKeyFrames></Storyboard></VisualState></VisualStateGroup></VisualStateManager.VisualStateGroups><ContentPresenter/></Border></ControlTemplate></Setter.Value></Setter></Style><ControlTemplateTargetType="ToggleButton"x:Key="ComboBoxToggleButtonTemplate"><Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinitionWidth="26"/></Grid.ColumnDefinitions><BorderGrid.ColumnSpan="2"Name="Border"BorderBrush="#16a085"CornerRadius="0"BorderThickness="1, 1, 1, 1"Background="#16a085"/><BorderGrid.Column="1"Margin="1, 1, 1, 1"BorderBrush="#16a085"Name="ButtonBorder"CornerRadius="0, 0, 0, 0"BorderThickness="0, 0, 0, 0"Background="#16a085"/><TextBlockName="Arrow"Grid.Column="1"Text="&#xf0d7;"Style="{StaticResource faFont}"SnapsToDevicePixels="True"FontSize="20"HorizontalAlignment="Left"VerticalAlignment="Center"Margin="3,3,3,3"Background="Transparent"Foreground="White"/></Grid><ControlTemplate.Triggers><TriggerProperty="UIElement.IsMouseOver"Value="True"><SetterProperty="Panel.Background"TargetName="ButtonBorder"Value="#16a085"/><SetterProperty="Shape.Fill"TargetName="Arrow"Value="Transparent"/></Trigger><TriggerProperty="ToggleButton.IsChecked"Value="True"><SetterProperty="Panel.Background"TargetName="ButtonBorder"Value="#16a085"/><SetterProperty="Shape.Fill"TargetName="Arrow"Value="Transparent"/></Trigger><TriggerProperty="UIElement.IsEnabled"Value="False"><SetterProperty="Panel.Background"TargetName="Border"Value="{StaticResource ComboBoxDisabledBackgroundBrush}"/><SetterProperty="Panel.Background"TargetName="ButtonBorder"Value="{StaticResource ComboBoxDisabledBackgroundBrush}"/><SetterProperty="Border.BorderBrush"TargetName="ButtonBorder"Value="{StaticResource ComboBoxDisabledBorderBrush}"/><SetterProperty="TextElement.Foreground"Value="{StaticResource ComboBoxDisabledForegroundBrush}"/><SetterProperty="Shape.Fill"TargetName="Arrow"Value="Transparent"/></Trigger></ControlTemplate.Triggers></ControlTemplate><Stylex:Key="ComboBoxFlatStyle"TargetType="{x:Type ComboBox}"><SetterProperty="UIElement.SnapsToDevicePixels"Value="True"/><SetterProperty="ScrollViewer.HorizontalScrollBarVisibility"Value="Auto"/><SetterProperty="ScrollViewer.VerticalScrollBarVisibility"Value="Auto"/><SetterProperty="ScrollViewer.CanContentScroll"Value="True"/><SetterProperty="TextElement.Foreground"Value="White"/><SetterProperty="FrameworkElement.FocusVisualStyle"Value="{x:Null}"/><SetterProperty="Control.Template"><Setter.Value><ControlTemplateTargetType="ComboBox"><Grid><ToggleButtonName="ToggleButton"Grid.Column="2"ClickMode="Press"Focusable="False"IsChecked="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"Template="{StaticResource ComboBoxToggleButtonTemplate}"/><ContentPresenterName="ContentSite"Margin="5, 3, 23, 3"IsHitTestVisible="False"HorizontalAlignment="Left"VerticalAlignment="Center"Content="{TemplateBinding SelectionBoxItem}"ContentTemplate="{TemplateBinding ComboBox.SelectionBoxItemTemplate}"ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/><TextBoxName="PART_EditableTextBox"Margin="3, 3, 23, 3"IsReadOnly="{TemplateBinding IsReadOnly}"Visibility="Hidden"Background="Transparent"HorizontalAlignment="Left"VerticalAlignment="Center"Foreground="{x:Static local:FlatColors.CLOUDS}"Focusable="True"><TextBox.Template><ControlTemplateTargetType="TextBox"><BorderName="PART_ContentHost"Focusable="False"/></ControlTemplate></TextBox.Template></TextBox><!-- Popup showing items --><PopupName="Popup"Placement="Bottom"Focusable="False"AllowsTransparency="True"IsOpen="{TemplateBinding ComboBox.IsDropDownOpen}"PopupAnimation="Slide"><GridName="DropDown"SnapsToDevicePixels="True"MinWidth="{TemplateBinding FrameworkElement.ActualWidth}"MaxHeight="{TemplateBinding ComboBox.MaxDropDownHeight}"><BorderName="DropDownBorder"Background="#ECF0F1"Margin="0, 1, 0, 0"CornerRadius="0"BorderThickness="1,1,1,1"BorderBrush="#ECF0F1"/><ScrollViewerMargin="1"SnapsToDevicePixels="True"Foreground="Black"FocusVisualStyle="{x:Null}"><ItemsPresenterKeyboardNavigation.DirectionalNavigation="Contained"/></ScrollViewer></Grid></Popup></Grid><ControlTemplate.Triggers><TriggerProperty="ItemsControl.HasItems"Value="False"><SetterProperty="FrameworkElement.MinHeight"TargetName="DropDownBorder"Value="95"/></Trigger><TriggerProperty="UIElement.IsEnabled"Value="False"><SetterProperty="TextElement.Foreground"Value="{StaticResource ComboBoxDisabledForegroundBrush}"/></Trigger><TriggerProperty="ItemsControl.IsGrouping"Value="True"><SetterProperty="ScrollViewer.CanContentScroll"Value="False"/></Trigger><TriggerProperty="ComboBox.IsEditable"Value="True"><SetterProperty="KeyboardNavigation.IsTabStop"Value="False"/><SetterProperty="UIElement.Visibility"TargetName="PART_EditableTextBox"Value="Visible"/><SetterProperty="UIElement.Visibility"TargetName="ContentSite"Value="Hidden"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style><StyleTargetType="{x:Type local:FlatComboBox}"BasedOn="{StaticResource ComboBoxFlatStyle}"><SetterProperty="FontSize"Value="{x:Static local:FlatFonts.contentFontSize}"></Setter><SetterProperty="Foreground"Value="White"></Setter></Style></ResourceDictionary>

   其中  <Style TargetType="{x:Type local:FlatComboBox}" BasedOn="{StaticResource ComboBoxFlatStyle}"  > 语句中的BasedOn表示继承关系,即一个新的Style可以通过BasedOn来继承,这样就可以更加方便的管理样式。另外,下拉框中的小三角形状是通过图标字体实现的,<TextBlock  Name="Arrow" Grid.Column="1"  Text="&#xf0d7;"  Style="{StaticResource faFont}" ...>  。

3 WPF FlatComboBox测试


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

<WpfControls:FlatComboBoxHorizontalAlignment="Left"Height="30"x:Name="ccb"Margin="424,181,0,0"VerticalAlignment="Top"Width="255"/>

其中的x:Name="ccb"给控件起一个名称,这样可以在后台用C#来进行访问,下面给出后台初始化数据的示例代码:

publicpartialclassMainWindow : Window{
publicMainWindow()
        {
InitializeComponent();
List<String>list=newList<string>();
list.Add("国学");
list.Add("高数");
list.Add("绘画");
this.ccb.ItemsSource=list;
        }
}

运行界面如下:

2.png

相关文章
WPF自定义控件05:ToggleButton
本文重点介绍WPF中如何实现自定义ToggleButton控件,它是一个开关控件,通过单击来进行状态的快速切换。
5171 0
WPF自定义控件05:ToggleButton
|
人工智能 C#
WPF自定义控件库之Window窗口
本文以自定义窗口为例,简述WPF开发中如何通过自定义控件来扩展功能和样式,仅供学习分享使用,如有不足之处,还请指正。
259 5
|
XML C# 数据格式
WPF中用户控件和自定义控件
无论是在WPF中还是WinForm中,都有用户控件(UserControl)和自定义控件(CustomControl),这两种控件都是对已有控件的封装,实现功能重用。但是两者还是有一些区别,本文对这两种控件进行讲解。
|
数据可视化 前端开发 C#
WPF自定义控件的三种方式
某些场景下,我们确实需要创建新的控件。此时,理解 WPF不同控件的创建方法就显得非常重要。 WPF 提供3个用于创建控件的方法,每个方法都提供不同的灵活度。
909 1
WPF自定义控件的三种方式
|
C# 容器
WPF自定义控件10:FlatListView
在不少的应用程序中,有时候需要使用ListView控件来显示一组集合数据,这样可以从一组数据中进行选择,让数据更加的规范,便于统计和分析。本文将介绍一下自定义的列表控件FlatListView,它与FlatCheckBox实现过程非常类似,它是继承自ListView,但使用自定义的UI样式来美化界面。
591 0
WPF自定义控件10:FlatListView
WPF自定义控件09:FlatWaveButton
按钮在很多应用程序中都是必不可少的控件,如果给按钮控件添加一些动画效果,比如单击它后会显示一个水波纹扩散的动画效果,那么感觉上更加的高级。本文将介绍一下自定义水波纹按钮控件FlatWaveButton,它是一个UserControl(FlatButton)控件,自身携带UI样式和后台逻辑。
660 0
WPF自定义控件09:FlatWaveButton
|
Web App开发 C#
WPF自定义控件08:FlatRoundImage
在不少的应用程序中,用户中心的个人页面经常需要显示头像,这个当前主流的做法就是用户上传一个图片,系统进行截取并显示为一个圆形的轮廓,即圆形的照片。本文将介绍一下自定义的图片控件FlatRoundImage,它是一个UserControl控件,自身携带UI样式和后台逻辑。
660 0
WPF自定义控件08:FlatRoundImage
WPF自定义控件07:FlatTextBox
本文将介绍一下自定义的文本框控件FlatTextBox,它与FlatCheckBox实现过程非常类似,它是继承自TextBox,但使用自定义的UI样式来美化界面,并添加了特有的一些依赖属性。
543 0
WPF自定义控件07:FlatTextBox
WPF自定义控件04:FlatRadioButton
本文通过在WPF中引入Font Awesome图标字体来实现自定义FlatRadioButton控件的UI绘图。用户只需要在窗体上引入自定义的FlatRadioButton控件即可使用具有Flat UI效果的控件,非常方便。
619 0
WPF自定义控件04:FlatRadioButton
WPF自定义控件03:FlatCheckBox
本文通过在WPF中引入Font Awesome图标字体来实现自定义FlatCheckBox控件的UI绘图。用户只需要在窗体上引入自定义的FlatCheckBox控件即可使用具有Flat UI效果的控件,非常方便。
745 0
WPF自定义控件03:FlatCheckBox