在不少的应用程序中,有时候需要使用ListView控件来显示一组集合数据,这样可以从一组数据中进行选择,让数据更加的规范,便于统计和分析。本文将介绍一下自定义的列表控件FlatListView,它与FlatCheckBox实现过程非常类似,它是继承自ListView,但使用自定义的UI样式来美化界面。下面将详细介绍具体的实现细节。
1 WPF项目结构
基于之前创建的WPF示例项目,在其中创建一个新的关于FlatListView的项目文件。本质上,FlatListView是继承ListView控件,利用ListView控件自身的属性和方法,可以减少FlatListView实现的难度和复杂度。首先,给出本项目文件结构,如下图所示:
其中的Fonts目录下存放各种图标字体文件,Style目录下存放各种控件的UI 样式定义文件,FlatListView.xaml就是FlatListView控件的样式定义文件。另外,需要将其注册到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"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatTextBox.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatListView.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary>
2 WPF FlatListView实现
首先在Yd.WpfControls项目中添加一个类FlatListView.cs,它继承自ListView控件,示例代码如下:
usingSystem.Windows; usingSystem.Windows.Controls; namespaceYd.WpfControls{ publicclassFlatListView : ListView { staticFlatListView() { DefaultStyleKeyProperty.OverrideMetadata(typeof(FlatListView), newFrameworkPropertyMetadata(typeof(FlatListView))); } } }
FlatListView控件的UI样式主要就是依靠FlatListView.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><SolidColorBrushx:Key="ListBox.Static.Background"Color="#34495e"/><SolidColorBrushx:Key="ListBox.Static.Border"Color="#34495e"/><SolidColorBrushx:Key="ListBox.Disabled.Background"Color="#FFFFFFFF"/><SolidColorBrushx:Key="ListBox.Disabled.Border"Color="#FFD9D9D9"/><Stylex:Key="Flat_ListViewStyle"TargetType="{x:Type ListView}"><SetterProperty="Background"Value="{StaticResource ListBox.Static.Background}"/><SetterProperty="BorderBrush"Value="{StaticResource ListBox.Static.Border}"/><SetterProperty="BorderThickness"Value="1"/><SetterProperty="Foreground"Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/><SetterProperty="ScrollViewer.HorizontalScrollBarVisibility"Value="Auto"/><SetterProperty="ScrollViewer.VerticalScrollBarVisibility"Value="Auto"/><SetterProperty="ScrollViewer.CanContentScroll"Value="true"/><SetterProperty="ScrollViewer.PanningMode"Value="Both"/><SetterProperty="Stylus.IsFlicksEnabled"Value="False"/><SetterProperty="VerticalContentAlignment"Value="Center"/><SetterProperty="Template"><Setter.Value><ControlTemplateTargetType="{x:Type ListView}"><Borderx:Name="Bd"Background="{TemplateBinding Background}"BorderThickness="{TemplateBinding BorderThickness}"BorderBrush="{TemplateBinding BorderBrush}"Padding="1"SnapsToDevicePixels="true"><ScrollViewerFocusable="false"Padding="{TemplateBinding Padding}"><ItemsPresenterSnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/></ScrollViewer></Border><ControlTemplate.Triggers><TriggerProperty="IsEnabled"Value="false"><SetterProperty="Background"TargetName="Bd"Value="{StaticResource ListBox.Disabled.Background}"/><SetterProperty="BorderBrush"TargetName="Bd"Value="{StaticResource ListBox.Disabled.Border}"/></Trigger><MultiTrigger><MultiTrigger.Conditions><ConditionProperty="IsGrouping"Value="true"/><ConditionProperty="VirtualizingPanel.IsVirtualizingWhenGrouping"Value="false"/></MultiTrigger.Conditions><SetterProperty="ScrollViewer.CanContentScroll"Value="false"/></MultiTrigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style><Stylex:Key="Flat_ItemHover"TargetType="{x:Type ListViewItem}"><SetterProperty="BorderThickness"Value="0"/><SetterProperty="Height"Value="30"/><Style.Triggers><TriggerProperty="IsMouseOver"Value="true"><SetterProperty="Background"Value="#2ecc71"/><SetterProperty="Foreground"Value="Orange"/><SetterProperty="Cursor"Value="Hand"/></Trigger><TriggerProperty="IsSelected"Value="true"><SetterProperty="Background"Value="#2ecc71"/><SetterProperty="Foreground"Value="Yellow"/><!--<Setter Property="FontWeight" Value="Bold" />--><SetterProperty="Cursor"Value="Hand"/></Trigger></Style.Triggers></Style><StyleTargetType="{x:Type local:FlatListView}"BasedOn="{StaticResource Flat_ListViewStyle}"><SetterProperty="FontSize"Value="{x:Static local:FlatFonts.contentFontSize}"></Setter><SetterProperty="Foreground"Value="White"></Setter><!-- Item Container样式 --><SetterProperty="ItemContainerStyle"Value="{StaticResource Flat_ItemHover}"></Setter><SetterProperty="Cursor"Value="Hand"/></Style></ResourceDictionary>
其中<Style TargetType="{x:Type local:FlatListView}" BasedOn="{StaticResource Flat_ListViewStyle}" 语句中的BasedOn表示继承关系,即一个新的Style可以通过BasedOn来继承,这样就可以更加方便的管理样式。另外,ListView每个Item容器的样式是通过ItemContainerStyle实现的,即 <Setter Property="ItemContainerStyle" Value="{StaticResource Flat_ItemHover}"></Setter> 。
3 WPF FlatListView测试
首先,需要重新生成一下项目文件,然后在WpfControls项目中添加Window8窗口,并添加自定义控件FlatListView,Window8.xaml示例代码如下:
<Windowxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfControls"xmlns:WpfControls="clr-namespace:Yd.WpfControls;assembly=Yd.WpfControls"x:Class="WpfControls.Window8"mc:Ignorable="d"Title="Window8"Height="350"Width="500"><Grid><WpfControls:FlatListViewName="flatListView"FontSize="13"><ListView.ItemTemplate><DataTemplate><WrapPanel><TextBlockText="{Binding Name}"/><TextBlockText=" ("/><TextBlockText="{Binding Counter}"Cursor="Hand"/><TextBlockText=")"/></WrapPanel></DataTemplate></ListView.ItemTemplate></WpfControls:FlatListView></Grid></Window>
其中的Name="flatListView"给控件起一个名称,这样可以在后台用C#来进行访问,下面给出后台初始化数据的示例代码:
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; usingSystem.Windows; usingSystem.Windows.Controls; usingSystem.Windows.Data; usingSystem.Windows.Documents; usingSystem.Windows.Input; usingSystem.Windows.Media; usingSystem.Windows.Media.Imaging; usingSystem.Windows.Shapes; namespaceWpfControls{ /// <summary>/// Window8.xaml 的交互逻辑/// </summary>publicpartialclassWindow8 : Window { publicWindow8() { InitializeComponent(); List<Classz>items=newList<Classz>(); items.Add(newClassz() { Name="Java语言编程", Counter=42 }); items.Add(newClassz() { Name="数据结构C++", Counter=39 }); items.Add(newClassz() { Name="FSharp编程基础", Counter=13 }); flatListView.ItemsSource=items; } publicclassClassz { publicstringName { get; set; } publicintCounter { get; set; } } } }
运行界面如下: