• WPF开发分页控件:实现可定制化分页功能及实现原理解析


    概要

      本文将详细介绍如何使用WPF(Windows Presentation Foundation)开发一个分页控件,并深入解析其实现原理。我们将通过使用XAML和C#代码相结合的方式构建分页控件,并确保它具有高度的可定制性,以便在不同的应用场景中满足各种需求。

    一.简介

      分页控件是在许多应用程序中常见的一种界面元素,特别是在数据展示的场景中。它允许用户浏览大量数据,并根据需要切换到不同的数据页。

    二.需求分析

      我们首先来分析一下一个分页控件的基本构成。

     

    2.1 总条目数(TotalItems)

      表示总数据量。

    2.2 每页条目数(PageSize)

      表示每页显示的条目数。

    2.3 总页数(PageCount)

      表示根据总条目数与每页条目数计算出来的页数。

    2.4 分页/页码按钮数量(PageNumberCount)

      分页控件中可以点击的页码按钮。

    2.5 当前页(CurrentPage)

      当前显示的页,通常高亮显示。

    三.控件命令和事件

    3.1 页面跳转命令(GoToPageCommand)

      该命令用于在XAML代码中触发页面跳转操作。

    3.2当前页变更事件

      当CurrentPage参数改变后触发该事件,通常在该事件中执行数据查询操作。

    四.代码实现

      通过以上原理分析,我们提取出了分页控件需要包含的基本要素,下面我们通过这些信息来组装成一个分页控件。

    复制代码
     1 <Style TargetType="{x:Type local:Pager}">
     2     <Setter Property="Template">
     3         <Setter.Value>
     4             <ControlTemplate TargetType="{x:Type local:Pager}">
     5                 <Border Background="{TemplateBinding Background}"
     6                             BorderBrush="{TemplateBinding BorderBrush}"
     7                             BorderThickness="{TemplateBinding BorderThickness}">
     8                     <StackPanel Orientation="Horizontal" ClipToBounds="True">
     9                         <Button Command="{x:Static local:Pager.GoToPageCommand}" CommandParameter="1" Margin="0,0,5,0" Content="首页">Button>
    10                         <Button Command="{x:Static local:Pager.GoToPageCommand}" CommandParameter="-" Margin="5,0" Content="上一页">Button>
    11                         <ItemsControl ItemsSource="{TemplateBinding PageButtons}">
    12                             <ItemsControl.ItemsPanel>
    13                                 <ItemsPanelTemplate>
    14                                     <StackPanel Orientation="Horizontal"/>
    15                                 ItemsPanelTemplate>
    16                             ItemsControl.ItemsPanel>
    17                             <ItemsControl.ItemTemplate>
    18                                 <DataTemplate>
    19                                     <ToggleButton MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}"              
    20                                                       Content="{Binding Page}"                        
    21                                                       IsChecked="{Binding IsCurrentPage}"                        
    22                                                       Command="{x:Static local:Pager.GoToPageCommand}"
    23                                                       CommandParameter="{Binding Page}"
    24                                                       Margin="5,0"/>
    25                                 DataTemplate>
    26                             ItemsControl.ItemTemplate>
    27                         ItemsControl>
    28                         <Button Command="{x:Static local:Pager.GoToPageCommand}" CommandParameter="+" Margin="5,0" Content="下一页">Button>
    29                         <Button Command="{x:Static local:Pager.GoToPageCommand}" CommandParameter="尾页" Margin="5,0,0,0" Content="{DynamicResource LastPage}">Button>
    30                     StackPanel>
    31                 Border>
    32             ControlTemplate>
    33         Setter.Value>
    34     Setter> 
    35 Style>
    复制代码

    五.多样化需求

      在不同的业务场景下需要的分页控件可能不尽相同,那么如何来满足多样化需求呢,答案就是自定义控件模板。下面演示几种常见的分页控件如何实现。

    只需要“上一页”、“下一页”的情况

    复制代码
     1 <Style TargetType="{x:Type Controls:Pager}">
     2     <Setter Property="Template">
     3         <Setter.Value>
     4             <ControlTemplate TargetType="{x:Type Controls:Pager}">
     5                 <Border Background="{TemplateBinding Background}"
     6                             BorderBrush="{TemplateBinding BorderBrush}"
     7                             BorderThickness="{TemplateBinding BorderThickness}">
     8                     <StackPanel Orientation="Horizontal" ClipToBounds="True">
     9                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="-" Margin="5,0" Content="{DynamicResource PreviousPage}">Button>
    10                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="+" Margin="5,0" Content="{DynamicResource NextPage}">Button>
    11                     StackPanel>
    12                 Border>
    13             ControlTemplate>
    14         Setter.Value>
    15     Setter>
    16 Style>
    复制代码

    只需要“首页”、“上一页”、“下一页”、“尾页”的情况。

    复制代码
     1 <Style TargetType="{x:Type Controls:Pager}">
     2     <Setter Property="Template">
     3         <Setter.Value>
     4             <ControlTemplate TargetType="{x:Type Controls:Pager}">
     5                 <Border Background="{TemplateBinding Background}"
     6                             BorderBrush="{TemplateBinding BorderBrush}"
     7                             BorderThickness="{TemplateBinding BorderThickness}">
     8                     <StackPanel Orientation="Horizontal" ClipToBounds="True">
     9                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="1" Margin="0,0,5,0" Content="{DynamicResource FirstPage}">Button>
    10                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="-" Margin="5,0" Content="{DynamicResource PreviousPage}">Button>
    11                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="+" Margin="5,0" Content="{DynamicResource NextPage}">Button>
    12                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="{TemplateBinding PageCount}" Margin="5,0,0,0" Content="{DynamicResource LastPage}">Button>
    13                     StackPanel>
    14                 Border>
    15             ControlTemplate>
    16         Setter.Value>
    17     Setter>
    18 Style>
    复制代码

    数字显示“首页”、“尾页”的情况。

    复制代码
     1 <Style TargetType="{x:Type Controls:Pager}">
     2     <Setter Property="Template">
     3         <Setter.Value>
     4             <ControlTemplate TargetType="{x:Type Controls:Pager}">
     5                 <Border Background="{TemplateBinding Background}"
     6                             BorderBrush="{TemplateBinding BorderBrush}"
     7                             BorderThickness="{TemplateBinding BorderThickness}">
     8                     <StackPanel Orientation="Horizontal" ClipToBounds="True">
     9                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" 
    10                                         CommandParameter="1" 
    11                                         Content="1"
    12                                         MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" 
    13                                         Margin="0,0,5,0">
    14                             <Button.Visibility>
    15                                 <MultiBinding Converter="{StaticResource PageNumberToVisibilityConverter}" ConverterParameter="First">
    16                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="CurrentPage"/>
    17                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="PageNumberCount"/>
    18                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="PageCount"/>
    19                                 MultiBinding>
    20                             Button.Visibility>
    21                         Button>
    22                         <Button IsEnabled="False" Margin="5,0" MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Content="...">
    23                             <Button.Visibility>
    24                                 <MultiBinding Converter="{StaticResource PageNumberToVisibilityConverter}" ConverterParameter="First">
    25                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="CurrentPage"/>
    26                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="PageNumberCount"/>
    27                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="PageCount"/>
    28                                 MultiBinding>
    29                             Button.Visibility>
    30                         Button>
    31                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="-" Margin="5,0" Content="{DynamicResource PreviousPage}">Button>
    32                         <ItemsControl ItemsSource="{TemplateBinding PageButtons}">
    33                             <ItemsControl.ItemsPanel>
    34                                 <ItemsPanelTemplate>
    35                                     <StackPanel Orientation="Horizontal"/>
    36                                 ItemsPanelTemplate>
    37                             ItemsControl.ItemsPanel>
    38                             <ItemsControl.ItemTemplate>
    39                                 <DataTemplate>
    40                                     <ToggleButton MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" 
    41                         Content="{Binding Page}" 
    42                         Margin="5,0" 
    43                         IsChecked="{Binding IsCurrentPage}"
    44                         Command="{x:Static Controls:Pager.GoToPageCommand}"
    45                         CommandParameter="{Binding Page}"/>
    46                                 DataTemplate>
    47                             ItemsControl.ItemTemplate>
    48                         ItemsControl>
    49                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="+" Margin="5,0" Content="{DynamicResource NextPage}">Button>
    50                         <Button IsEnabled="False" Margin="5,0" MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Content="...">
    51                             <Button.Visibility>
    52                                 <MultiBinding Converter="{StaticResource PageNumberToVisibilityConverter}">
    53                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="CurrentPage"/>
    54                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="PageNumberCount"/>
    55                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="PageCount"/>
    56                                 MultiBinding>
    57                             Button.Visibility>
    58                         Button>
    59                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" 
    60                                         CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Controls:Pager},Path=PageCount}" 
    61                                         Content="{Binding RelativeSource={RelativeSource AncestorType=Controls:Pager},Path=PageCount}" 
    62                                         MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}"
    63                                         Margin="5,0,0,0">
    64                             <Button.Visibility>
    65                                 <MultiBinding Converter="{StaticResource PageNumberToVisibilityConverter}">
    66                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="CurrentPage"/>
    67                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="PageNumberCount"/>
    68                                     <Binding RelativeSource="{RelativeSource AncestorType=Controls:Pager}" Path="PageCount"/>
    69                                 MultiBinding>
    70                             Button.Visibility>
    71                         Button>
    72 
    73                         <StackPanel Orientation="Horizontal" Margin="5,0,0,0">
    74                             <TextBlock Text="转到" VerticalAlignment="Center"/>
    75                             <TextBox x:Name="tbox_Page" Width="40" Margin="5,0" Padding="5" HorizontalContentAlignment="Center" VerticalAlignment="Center"/>
    76                             <TextBlock Text="页" VerticalAlignment="Center"/>
    77                             <Button Margin="5,0,0,0" Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="{Binding ElementName=tbox_Page,Path=Text}">确定Button>
    78                         StackPanel>
    79                     StackPanel>
    80                 Border>
    81             ControlTemplate>
    82         Setter.Value>
    83     Setter>
    84 Style>
    复制代码

     可以调整每页显示条目,可以显示总页数,可以跳转到指定页的情况。

    复制代码
     1 <Style TargetType="{x:Type Controls:Pager}">
     2     <Setter Property="Template">
     3         <Setter.Value>
     4             <ControlTemplate TargetType="{x:Type Controls:Pager}">
     5                 <Border Background="{TemplateBinding Background}"
     6                             BorderBrush="{TemplateBinding BorderBrush}"
     7                             BorderThickness="{TemplateBinding BorderThickness}">
     8                     <StackPanel Orientation="Horizontal" ClipToBounds="True">
     9                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="1" Margin="0,0,5,0" MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Content="{DynamicResource FirstPage}">Button>
    10                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="-" Margin="5,0" MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Content="{DynamicResource PreviousPage}">Button>
    11                         <ItemsControl ItemsSource="{TemplateBinding PageButtons}">
    12                             <ItemsControl.ItemsPanel>
    13                                 <ItemsPanelTemplate>
    14                                     <StackPanel Orientation="Horizontal"/>
    15                                 ItemsPanelTemplate>
    16                             ItemsControl.ItemsPanel>
    17                             <ItemsControl.ItemTemplate>
    18                                 <DataTemplate>
    19                                     <ToggleButton MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" 
    20                         Content="{Binding Page}" 
    21                         Margin="5,0" 
    22                         IsChecked="{Binding IsCurrentPage}"
    23                         Command="{x:Static Controls:Pager.GoToPageCommand}"
    24                         CommandParameter="{Binding Page}"/>
    25                                 DataTemplate>
    26                             ItemsControl.ItemTemplate>
    27                         ItemsControl>
    28                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="+" Margin="5,0" MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Content="{DynamicResource NextPage}">Button>
    29                         <Button Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="{TemplateBinding PageCount}" Margin="5,0,0,0" MinWidth="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" Content="{DynamicResource LastPage}">Button>
    30                         <StackPanel Orientation="Horizontal" Margin="5,0,0,0">
    31                             <TextBlock Margin="0,0,5,0" Text="每页" VerticalAlignment="Center"/>
    32                             <ComboBox Margin="5,0" SelectedIndex="0" VerticalContentAlignment="Center" SelectedItem="{Binding RelativeSource={RelativeSource AncestorType=Controls:Pager},Path=PageSize,Mode=OneWayToSource}">
    33                                 <sys:Int32>5sys:Int32>
    34                                 <sys:Int32>10sys:Int32>
    35                                 <sys:Int32>15sys:Int32>
    36                                 <sys:Int32>20sys:Int32>
    37                             ComboBox>
    38                             <TextBlock Text="条" VerticalAlignment="Center" Margin="5,0"/>
    39                             <TextBlock VerticalAlignment="Center" Margin="5,0">
    40                                         <Run Text="共"/>
    41                                         <Run Text="{Binding RelativeSource={RelativeSource AncestorType=Controls:Pager},Path=PageCount}"/>
    42                                         <Run Text="页"/>
    43                             TextBlock>
    44                             <TextBlock Text="转到" VerticalAlignment="Center"/>
    45                             <TextBox x:Name="tbox_Page" Width="40" Margin="5,0" Padding="5" HorizontalContentAlignment="Center" VerticalAlignment="Center"/>
    46                             <TextBlock Text="页" VerticalAlignment="Center"/>
    47                             <Button Margin="5,0,0,0" Command="{x:Static Controls:Pager.GoToPageCommand}" CommandParameter="{Binding ElementName=tbox_Page,Path=Text}">确定Button>
    48                         StackPanel>
    49                     StackPanel>
    50                 Border>
    51             ControlTemplate>
    52         Setter.Value>
    53     Setter>
    54 Style>
    复制代码

      除了修改模板实现不同的形态的分页控件以外,还可以用图标替换掉“首页”、“上一页”、“下一页”、”尾页”等文字。

    六.个性化控件外观

      项目中的界面外观可能多种多样,有自己写的控件样式,也有使用第三方UI库的样式,如何跟它们搭配使用呢。

    自定义控件样式

    复制代码
    1 <Style TargetType="Button">
    2     <Setter Property="Padding" Value="5"/>
    3     <Setter Property="Background" Value="Red"/>
    4 Style>
    5 <Style TargetType="ToggleButton">
    6     <Setter Property="Padding" Value="5"/>
    7     <Setter Property="Background" Value="Red"/>
    8 Style>
    复制代码

     使用第三方UI库

    1.HandyControl

    复制代码
    1 <ResourceDictionary>
    2     <ResourceDictionary.MergedDictionaries>
    3         <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml" />
    4         <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml" />
    5     ResourceDictionary.MergedDictionaries>
    6 ResourceDictionary>
    复制代码

     2.MaterialDesign

    复制代码
    1 <ResourceDictionary>
    2     <ResourceDictionary.MergedDictionaries>
    3         <materialDesign:CustomColorTheme BaseTheme="Light" PrimaryColor="#FF3561FF" SecondaryColor="#FF3561FF" />
    4         <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
    5     ResourceDictionary.MergedDictionaries>
    6 ResourceDictionary>
    复制代码

     

     技术交流群
     
     联系方式
  • 相关阅读:
    QT进阶---------pro项目文件中的常用命令 (第三天)
    Pytorch深度强化学习1-2:详解K摇臂赌博机模型和ϵ-贪心算法
    数电学习(五、触发器)(一)
    什么是RESTful API,Spring MVC如何支持RESTful架构
    第5章 Object Interactive
    提升办公效率,畅享多功能办公笔记软件Notion for Mac
    java后端web前端10套项目开发案例源码,毕设,期末作业
    Windows 10 也能安装Kafka?这篇教程让你轻松掌握!
    移动硬盘被格式化了如何恢复数据?四步教你如何恢复
    超市营业额数据分析
  • 原文地址:https://www.cnblogs.com/qushi2020/p/17932338.html