在对大量数据进行可视化展示的时候,我们常常会用到分页的方法,这样一方面可以避免因大量数据在同一页上展示所产生的计算机性能问题,同时,每页上相对少量的数据也有利于浏览时候的快速定位。但是在WPF中并没有这样一个用于分页的预定义控件,因此需要用户自己去实现这样一个应用逻辑。为便于复用,可以将用于分页的内容,包括UI界面和控制逻辑,封装成一个WPF的自定义控件。
一 设计思路
经简单的分析可知,一个较为通用的分页控件应该接受以下几个核心的数据:1 总的数据量 2 每页可显示的最大数据 3 可选择的页码数量,同时需要向使用者提供两个核心的数据:1 每页可显示的最大数据 2 当前选择的页数。
为了便于灵活使用,还应满足一些控制逻辑:1 每页显示的最大数据可以通过选择框来实时切换,2 要能快速跳转到首页和尾页, 3 在切换页码的时候,要能刷新可选择的页码。
除此之外,还有一些用于界面设置的属性,如定义页码按钮的背景,字体颜色等等。
二 代码结构
如图,利用WPF自定义控件(CustomControl)的方式对分页控件进行封装,其中Pagination.xaml为控件的默认模板,Pagination.cs为控件的逻辑控制代码。BoolToVisibilityConverter.cs用于绑定数据类型转换的数据转换类(bool值转元素可见性的Visibility)。
三 模板代码
控件的默认模板包括:一个ComboBox,用于控制每页可显示数据的最大数量;四个Button,用于跳转到首页、尾页、上一页、下一页四个操作的控制;一个ListBox,用于显示当前可供选择的页码;一个TextBlock,用于展示分页信息。
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Pagination"
xmlns:cvt="clr-namespace:Paginations.Converters">
<cvt:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
<Style x:Key="ListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="{Binding PageSelectorBackground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:Pagination}}"/>
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" Height="auto" Margin="1" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="Stretch" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Bd"
Property="BorderBrush"
Value="Transparent" />
<Setter TargetName="Bd"
Property="Background"
Value="Transparent" />
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background"
TargetName="Bd"
Value="{Binding SelectedPageBackground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:Pagination}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:Pagination}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Pagination}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid Margin="0,8,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Height="32" Grid.Column="0">
<!--每页数据量选择-->
<ComboBox x:Name="PART_ComboBox"
Visibility="{TemplateBinding IsShowPageDataCountSelector,Converter={StaticResource BoolToVisibilityConverter}}"
Width="65" Height="25"
Background="Transparent"
Padding="5,0,0,0"
SelectedIndex="0"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
ItemsSource="{TemplateBinding PageDataCountCollection}">
</ComboBox>
<Button x:Name="PART_ButtonFirstPage"
Content="首页"
Width="46"
Padding="0"
Margin="10,0,0,0"
BorderThickness="1"/>
<Button x:Name="PART_ButtonPrePage"
Content="《"