zoukankan      html  css  js  c++  java
  • WPF管理系统自定义分页控件

      最近做一个演示的管理系统项目,需要用到分页控件,在网上找了很多,依然找到与UI模版匹配的,最后干脆自己写一个。

      分页控件分析:

        1、分页控件分简单显示和复杂显示两种;

        2、包含上一页、下一页以及页码明细逻辑处理;

        3、页码总数小于7时显示默认显示,大于7时切换复杂显示;

        4、页码数、索引、总条数计算等;

      先来一张效果图:  

      

      

      啥也不说了直接上代码

      MISPager.xaml部分

    <ResourceDictionary               
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:mis="clr-namespace:MIS.ClientUI.Controls"
                 mc:Ignorable="d" >
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MIS.ClientUI;component/Themes/Corlors.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MIS.ClientUI;component/Themes/Share.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <!--系统默认的分页控件-->
        <Style x:Key="MISDefaultDataPagerStyle" TargetType="{x:Type mis:MISPager}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type mis:MISPager}">
                        <Grid Margin="0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <StackPanel Margin="0" Orientation="Horizontal">
                                <TextBlock TextWrapping="Wrap" Text="" Margin="0" VerticalAlignment="Center"/>
                                <TextBlock x:Name="PART_Count" HorizontalAlignment="Stretch" TextWrapping="Wrap" VerticalAlignment="Center" Text="1256" Foreground="#FF056DAE"/>
                                <TextBlock TextWrapping="Wrap" Text="条记录,当前显示第" Margin="0" VerticalAlignment="Center"/>
                                <TextBlock x:Name="PART_PageIndex" TextWrapping="Wrap" Text=" 2 " Margin="0" VerticalAlignment="Center" Foreground="#FF056DAE"/>
                                <TextBlock TextWrapping="Wrap" Text="" Margin="0" VerticalAlignment="Center"/>
                            </StackPanel>
                            <Border BorderBrush="Black" Grid.Column="1" Margin="0" HorizontalAlignment="Right">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="40"/>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="40"/>
                                    </Grid.ColumnDefinitions>
                                    <Border BorderBrush="#FFDDDDDD" BorderThickness="1,1,0,1" HorizontalAlignment="Stretch" Height="Auto" VerticalAlignment="Stretch" Width="Auto" CornerRadius="2,0,0,2">
                                        <mis:MISImageButton  BorderThickness="0" MISCornerRadius="0" GeometryIcon="{DynamicResource DefaultDataPagerPreviouspage}"  Style="{DynamicResource DefaultISvgImageButtonStyle}"  x:Name="PART_Previouspage" />
                                    </Border>
                                    <Border Grid.ColumnSpan="1" HorizontalAlignment="Stretch" Height="Auto" VerticalAlignment="Stretch" Width="Auto" Grid.Column="1" BorderBrush="#FFDDDDDD" BorderThickness="0,1">
                                        <StackPanel x:Name="PART_Content" Orientation="Horizontal">
                                        </StackPanel>
                                    </Border>
                                    <Border BorderBrush="#FFDDDDDD" BorderThickness="1" Margin="0" Grid.Column="2" CornerRadius="0,2,2,0">
                                        <mis:MISImageButton BorderThickness="0" MISCornerRadius="0" GeometryIcon="{DynamicResource DefaultDataPagerNextpage}"  x:Name="PART_Nextpage" Style="{DynamicResource DefaultISvgImageButtonStyle}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0"/>
                                    </Border>
                                </Grid>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
    </ResourceDictionary>

    MISPager.cs部分

      1 namespace MIS.ClientUI.Controls
      2 {
      3     /// <summary>
      4     /// 分页控件
      5     /// </summary>
      6     [TemplatePart(Name = MISPager.MIS_PART_CONTENT, Type = typeof(StackPanel))]
      7     [TemplatePart(Name = MISPager.MIS_PART_PREVIOUSPAGE, Type = typeof(MISImageButton))]
      8     [TemplatePart(Name = MISPager.MIS_PART_NEXTPAGE, Type = typeof(MISImageButton))]
      9     [TemplatePart(Name = MISPager.MIS_PART_COUNT, Type = typeof(TextBlock))]
     10     [TemplatePart(Name = MISPager.MIS_PART_PAGEINDEX, Type = typeof(TextBlock))]
     11     public partial class MISPager : Control
     12     {
     13         private const String MIS_PART_CONTENT = "PART_Content";
     14         private const String MIS_PART_PREVIOUSPAGE = "PART_Previouspage";
     15         private const String MIS_PART_NEXTPAGE = "PART_Nextpage";
     16         private const String MIS_PART_COUNT = "PART_Count";
     17         private const String MIS_PART_PAGEINDEX = "PART_PageIndex";
     18 
     19         private MISImageButton PART_Nextpage;  //下一页事件
     20         private MISImageButton PART_Previouspage; //上一页事件
     21         private StackPanel PART_Content;  //子页码
     22         private TextBlock PART_Count;
     23         private TextBlock PART_PageIndex;
     24 
     25         private PagerType mPagerType = PagerType.Default;  //当前分页控件类型,复杂、默认
     26         private List<Int32> mCurrentPagers = new List<Int32>(); //当前分页控件显示的页码索引
     27         private Boolean mCurrentIsAddEllipsisCtrl = false;  //当前是否已添加省略号控件(当前还是可以直接在集合控件中比对)
     28         
     29         public MISPager()
     30         {
     31 
     32         }
     33 
     34         //初始化控件时调用的系统方法
     35         public override void OnApplyTemplate()
     36         {
     37             base.OnApplyTemplate();
     38             this.PART_Content = this.GetTemplateChild(MISPager.MIS_PART_CONTENT) as StackPanel;
     39             this.PART_Nextpage = this.GetTemplateChild(MISPager.MIS_PART_NEXTPAGE) as MISImageButton;
     40             this.PART_Previouspage = this.GetTemplateChild(MISPager.MIS_PART_PREVIOUSPAGE) as MISImageButton;
     41             this.PART_Count = this.GetTemplateChild(MISPager.MIS_PART_COUNT) as TextBlock;
     42             this.PART_PageIndex = this.GetTemplateChild(MISPager.MIS_PART_PAGEINDEX) as TextBlock;
     43             //计算页码数
     44             this.PageCount = (Int32)Math.Ceiling((Double)this.Total / (Double)this.PageSize);
     45             this.PART_Count.Text = this.Total.ToString();
     46             //当总页码小于7页,显示1、2、3、4、5、6、7
     47             if (this.PageCount <= 7)
     48             {
     49                 this.mPagerType = PagerType.Default;
     50                 for (int i = 0; i < this.PageCount; i++)
     51                 {
     52                     var misImgBtn = new MISLinkButton()
     53                     {
     54                         Content = (i + 1).ToString(),
     55                         Width = 35,
     56                         BorderThickness = new Thickness(1, 0, 0, 0),
     57                         Style = Application.Current.FindResource("DefaultLinkButton2Style") as Style
     58                     };
     59                     this.mCurrentPagers.Add((i + 1));
     60                     misImgBtn.Click += OnMisImgBtn_Click;
     61                     if (this.PART_Content != null)
     62                     {
     63                         this.PART_Content.Children.Add(misImgBtn);
     64                     }
     65                 }
     66             }
     67             else
     68             {
     69                 this.mPagerType = PagerType.Complex;
     70                 for (int i = 0; i < 5; i++)
     71                 {
     72                     var misImgBtn = new MISLinkButton() { Content = (i + 1).ToString(), Width = 35, BorderThickness = new Thickness(1, 0, 0, 0), Style = Application.Current.FindResource("DefaultLinkButton2Style") as Style };
     73                     misImgBtn.Click += OnMisImgBtn_Click;
     74                     if (i.Equals(0)) misImgBtn.Tag = 0;  //设置左控制点
     75                     if (i.Equals(4)) misImgBtn.Tag = 5;  //设置右控制点
     76                     this.mCurrentPagers.Add((i + 1));
     77                     if (this.PART_Content != null)
     78                     {
     79                         this.PART_Content.Children.Add(misImgBtn);
     80                     }
     81                 }
     82                 this.PART_Content.Children.Add(new MISLinkButton() { Content = "...", Width = 35, BorderThickness = new Thickness(1, 0, 0, 0), Style = Application.Current.FindResource("DefaultLinkButton3Style") as Style });
     83                 this.PART_Content.Children.Add(new MISLinkButton() { Content = this.PageCount.ToString(), Width = 35, BorderThickness = new Thickness(1, 0, 0, 0), Style = Application.Current.FindResource("DefaultLinkButton2Style") as Style });
     84             }
     85             this.SetLinkButtonFocus(0);
     86             this._SetNextpageAndPreviouspageState();
     87             if (this.PART_Previouspage != null)
     88             {
     89                 this.PART_Previouspage.Click += OnPART_Previouspage_Click;
     90             }
     91             if (this.PART_Nextpage != null)
     92             {
     93                 this.PART_Nextpage.Click += OnPART_Nextpage_Click;
     94             }
     95         }
     96 
     97         #region 依赖属性
     98 
     99         #region 当前DataGrid显示的数据总条数,用于计算页码数
    100         /// <summary>
    101         /// 当前DataGrid显示的数据总条数,用于计算页码数
    102         /// </summary>
    103         public Int32 Total
    104         {
    105             get { return (Int32)GetValue(TotalProperty); }
    106             set { SetValue(TotalProperty, value); }
    107         }
    108 
    109         public static readonly DependencyProperty TotalProperty =
    110             DependencyProperty.Register("Total", typeof(Int32), typeof(MISPager), new PropertyMetadata(0));
    111 
    112         #endregion
    113 
    114         #region 当前DataGrid每页显示条数,用于计算页码数
    115         /// <summary>
    116         /// 每页显示条数
    117         /// </summary>
    118         public Int32 PageSize
    119         {
    120             get { return (Int32)GetValue(PageSizeProperty); }
    121             set { SetValue(PageSizeProperty, value); }
    122         }
    123 
    124         public static readonly DependencyProperty PageSizeProperty =
    125             DependencyProperty.Register("PageSize", typeof(Int32), typeof(MISPager), new PropertyMetadata(10));
    126 
    127 
    128         #endregion
    129 
    130         #region 当前DataGrid当前页码索引
    131 
    132         /// <summary>
    133         /// 页码索引
    134         /// </summary>
    135         public Int32 PageIndex
    136         {
    137             get { return (Int32)GetValue(PageIndexProperty); }
    138             set { SetValue(PageIndexProperty, value); }
    139         }
    140 
    141         public static readonly DependencyProperty PageIndexProperty =
    142             DependencyProperty.Register("PageIndex", typeof(Int32), typeof(MISPager), new FrameworkPropertyMetadata(1));
    143 
    144 
    145         #endregion
    146 
    147         #region 当前DataGrid总页数
    148         /// <summary>
    149         /// 页码数
    150         /// </summary>
    151         public Int32 PageCount
    152         {
    153             get { return (Int32)GetValue(PageCountProperty); }
    154             set { SetValue(PageCountProperty, value); }
    155         }
    156 
    157         public static readonly DependencyProperty PageCountProperty =
    158             DependencyProperty.Register("PageCount", typeof(Int32), typeof(MISPager), new PropertyMetadata(0));
    159 
    160         #endregion
    161 
    162         #endregion
    163 
    164         #region 路由事件
    165 
    166         //注册分页路由事件
    167         public static readonly RoutedEvent PageChangedEvent = EventManager.RegisterRoutedEvent("PageChanged",
    168             RoutingStrategy.Bubble, typeof(EventHandler<PageChangedEventArgs>), typeof(MISPager));
    169 
    170 
    171         public event EventHandler<PageChangedEventArgs> PageChanged
    172         {
    173             add
    174             {
    175                 this.AddHandler(PageChangedEvent, value);
    176             }
    177             remove
    178             {
    179                 this.RemoveHandler(PageChangedEvent, value);
    180             }
    181         }
    182 
    183 
    184         #endregion
    185 
    186         #region 私有方法
    187 
    188         /// <summary>
    189         /// 计算当前选中的分页按钮的索引
    190         /// </summary>
    191         private Int32 CalculationCurrentSelectPagerButtonWithIndex()
    192         {
    193             //当前控件显示的页码集合
    194             return this.mCurrentPagers.FindIndex((o) => { return o == this.PageIndex; });
    195         }
    196         /// <summary>
    197         /// 维护当前分页控件显示的页码数据
    198         /// </summary>
    199         /// <param name="addSubtract"></param>
    200         private void _MaintainCurrentPagers(AddSubtract addSubtract)
    201         {
    202             if (addSubtract == AddSubtract.Add)
    203             {
    204                 for (int i = 0; i < this.mCurrentPagers.Count; i++)
    205                 {
    206                     this.mCurrentPagers[i] = this.mCurrentPagers[i] + 1;
    207                 }
    208             }
    209             if (addSubtract == AddSubtract.subtract)
    210             {
    211                 for (int i = 0; i < this.mCurrentPagers.Count; i++)
    212                 {
    213                     this.mCurrentPagers[i] = this.mCurrentPagers[i] - 1;
    214                 }
    215             }
    216 
    217         }
    218         /// <summary>
    219         /// 下一页
    220         /// </summary>
    221         private void OnPART_Nextpage_Click(object sender, RoutedEventArgs e)
    222         {
    223             var _index = this.CalculationCurrentSelectPagerButtonWithIndex() + 1;
    224             this.PageIndex++;
    225             this._SetNextpageAndPreviouspageState();
    226             if (this.mPagerType == PagerType.Complex) //复杂分页有效
    227             {
    228                 // _index == 4 时为右侧控制点
    229                 if (_index == 4)
    230                 {
    231                     if (this.PageIndex == this.PageCount - 1)
    232                     {
    233                         this.PART_Nextpage.IsEnabled = false; //设置下一页不可用
    234                     }
    235                     //检测当前是否已添加省略号控件
    236                     if (!this.mCurrentIsAddEllipsisCtrl)
    237                     {
    238                         this.mCurrentIsAddEllipsisCtrl = true;
    239                         //在翻页控件第一个位置添加一个省略号控件
    240                         this.PART_Content.Children.Insert(0, new MISLinkButton() { Content = "...", Width = 35, BorderThickness = new Thickness(1, 0, 0, 0), Style = Application.Current.FindResource("DefaultLinkButton3Style") as Style });
    241                     }
    242                     //刷新UI(所有的分页控件加1)
    243                     this._RefreshPager(AddSubtract.Add);
    244                     this._MaintainCurrentPagers(AddSubtract.Add);
    245                 }
    246                 else
    247                 {
    248                     this.SetLinkButtonFocus(_index);
    249                 }
    250             }
    251             else
    252             {
    253                 //if (this.PageIndex == this.PageCount ) return;
    254                 this.SetLinkButtonFocus(_index);
    255             }
    256 
    257         }
    258         /// <summary>
    259         /// 上一页
    260         /// </summary>
    261         private void OnPART_Previouspage_Click(object sender, RoutedEventArgs e)
    262         {
    263             //当前PageIndex在界面上显示的索引,用于判断控制点   
    264             var _index = this.CalculationCurrentSelectPagerButtonWithIndex() - 1;
    265             this.PageIndex--;
    266             this._SetNextpageAndPreviouspageState();
    267             if (this.mPagerType == PagerType.Complex)  //复杂分页有效
    268             {
    269                 if (this.PageIndex == 1)
    270                 {
    271                     if (this.mCurrentIsAddEllipsisCtrl)
    272                     {
    273                         this.mCurrentIsAddEllipsisCtrl = false;
    274                         this.PART_Content.Children.RemoveAt(0);
    275                         this.SetLinkButtonFocus(0);
    276                     }
    277                     return;
    278                 }
    279                 if (_index == 0) //当前位置在左控制点时
    280                 {
    281                     //刷新UI(所有的分页控件减1)
    282                     this._RefreshPager(AddSubtract.subtract);
    283                     this._MaintainCurrentPagers(AddSubtract.subtract);
    284                 }
    285                 else
    286                 {
    287                     this.SetLinkButtonFocus(_index);
    288                 }
    289             }
    290             else
    291             {
    292                 //if (this.PageIndex == 1) return;
    293                 this.SetLinkButtonFocus(_index);
    294             }
    295         }
    296 
    297         private void SetLinkButtonFocus(Int32 index)
    298         {
    299             if (this.mCurrentIsAddEllipsisCtrl) //包含省略号控件
    300             {
    301                 this.PART_Content.Children[index + 1].Focus();
    302             }
    303             else
    304             {
    305                 this.PART_Content.Children[index].Focus();
    306             }
    307         }
    308 
    309         protected virtual void OnPageChanged()
    310         {
    311             var eventArgs = new PageChangedEventArgs(this.PageIndex) { RoutedEvent = PageChangedEvent, Source = this };
    312             this.RaiseEvent(eventArgs);
    313         }
    314 
    315         private void _RefreshPager(AddSubtract addSubtract)
    316         {
    317             /*
    318              * 1、默认分页的按钮为7个
    319              * 2、当分页总数小于等于7时,直接显示1-7个分页按钮
    320              * 3、当分页总数大于7时,显示当时为1、2、3、4、5、...、999(999为总页数)
    321              * 4、
    322              * **/
    323             if (this.PART_Content.Children.Count > 0)
    324             {
    325                 int _index = 0;  //
    326                 int _contentCount = this.PART_Content.Children.Count;
    327                 if (this.mCurrentIsAddEllipsisCtrl) //当前包含前缀省略号控件
    328                 {
    329                     _index = 1;
    330                     _contentCount = _contentCount - 1;
    331                 }
    332                 for (int i = 0; i < _contentCount - 2; i++)
    333                 {
    334                     var misLinkBtn = this.PART_Content.Children[_index] as MISLinkButton;
    335                     if (misLinkBtn != null)
    336                     {
    337                         misLinkBtn.Content = addSubtract == AddSubtract.Add ? (Convert.ToInt32(misLinkBtn.Content) + 1).ToString() : (Convert.ToInt32(misLinkBtn.Content) - 1).ToString();
    338                     }
    339                     _index++;
    340                 }
    341                 if (addSubtract == AddSubtract.Add)
    342                 {
    343                     //设置倒数第一个按钮会选中状态
    344                     this.PART_Content.Children[_index - 2].Focus();
    345                 }
    346                 else
    347                 {   //设置第二个按钮会选中状态
    348                     if (this.mCurrentIsAddEllipsisCtrl)
    349                     {
    350                         this.PART_Content.Children[2].Focus();
    351                     }
    352                     else
    353                     {
    354                         this.PART_Content.Children[1].Focus();
    355                     }
    356                 }
    357             }
    358 
    359 
    360 
    361 
    362 
    363 
    364 
    365         }
    366 
    367         /// <summary>
    368         /// 设置上一页下一页按钮显示状态
    369         /// </summary>
    370         private void _SetNextpageAndPreviouspageState()
    371         {
    372             if (this.PageIndex == 1)
    373             {
    374                 this.PART_Previouspage.IsEnabled = false;
    375             }
    376             if (this.PageIndex > 1)
    377             {
    378                 this.PART_Previouspage.IsEnabled = true;
    379                 this.PART_Nextpage.IsEnabled = true;
    380             }
    381             if (this.mPagerType == PagerType.Complex)
    382             {
    383                 if (this.PageIndex == this.PageCount - 1)
    384                 {
    385                     this.PART_Previouspage.IsEnabled = true;
    386                     this.PART_Nextpage.IsEnabled = false;
    387                 }
    388             }
    389             else
    390             {
    391                 if (this.PageIndex == this.PageCount)
    392                 {
    393                     this.PART_Previouspage.IsEnabled = true;
    394                     this.PART_Nextpage.IsEnabled = false;
    395                 }
    396             }
    397             this.PART_PageIndex.Text = this.PageIndex.ToString();
    398         }
    399         /// <summary>
    400         /// 页码索引点击事件
    401         /// </summary>
    402         /// <param name="sender"></param>
    403         /// <param name="e"></param>
    404         private void OnMisImgBtn_Click(object sender, RoutedEventArgs e)
    405         {
    406             //获取当前点击的PageIndex
    407             var misImgBtn = sender as MISLinkButton;
    408             this.PageIndex = Convert.ToInt32(misImgBtn.Content);
    409             this._SetNextpageAndPreviouspageState();
    410             //当为复杂控件时处理
    411             if (this.mPagerType == PagerType.Complex)
    412             {
    413                 this._RefreshPager(misImgBtn);
    414             }
    415             //执行路由回调
    416             OnPageChanged();
    417         }
    418 
    419         private void _RefreshPager(MISLinkButton misImgBtn)
    420         {
    421             //对比点击的控件
    422             if (misImgBtn.Tag != null)
    423             {
    424                 if (misImgBtn.Tag.Equals(0))
    425                 {
    426                     if (this.PageIndex > 1)
    427                     {
    428                         if (this.PageIndex == 2 && this.mCurrentIsAddEllipsisCtrl) //当前点击第二页时,显示第一个并移除左侧的省略号控件
    429                         {
    430                             this.mCurrentIsAddEllipsisCtrl = false;
    431                             this.PART_Content.Children.RemoveAt(0);
    432                         }
    433                         //刷新UI(所有的分页控件减1)
    434                         this._RefreshPager(AddSubtract.subtract);
    435                         this._MaintainCurrentPagers(AddSubtract.subtract);
    436                     }
    437                 }
    438                 if (misImgBtn.Tag.Equals(5))
    439                 {
    440                     //检测当前是否已添加省略号控件
    441                     if (!this.mCurrentIsAddEllipsisCtrl)
    442                     {
    443                         this.mCurrentIsAddEllipsisCtrl = true;
    444                         //在翻页控件第一个位置添加一个省略号控件
    445                         this.PART_Content.Children.Insert(0, new MISLinkButton() { Content = "...", Width = 35, BorderThickness = new Thickness(1, 0, 0, 0), Style = Application.Current.FindResource("DefaultLinkButton3Style") as Style });
    446                     }
    447                     //刷新UI(所有的分页控件加1)
    448                     this._RefreshPager(AddSubtract.Add);
    449                     this._MaintainCurrentPagers(AddSubtract.Add);
    450                 }
    451             }
    452         #endregion
    453         }
    454     }
    455 
    456     /// <summary>
    457     /// 分页事件参数
    458     /// </summary>
    459     public class PageChangedEventArgs : RoutedEventArgs
    460     {
    461 
    462         public int PageIndex
    463         {
    464             get;
    465             set;
    466         }
    467 
    468         public PageChangedEventArgs(int pageIndex)
    469             : base()
    470         {
    471             PageIndex = pageIndex;
    472         }
    473     }
    474 
    475     /// <summary>
    476     /// 分页控件类型
    477     /// </summary>
    478     public enum PagerType
    479     {
    480         /// <summary>
    481         /// 默认
    482         /// </summary>
    483         Default,
    484         /// <summary>
    485         /// 复杂
    486         /// </summary>
    487         Complex
    488     }
    489 
    490     public enum AddSubtract
    491     {
    492         Add, subtract
    493     }
    494 }
  • 相关阅读:
    Leetcode Binary Tree Preorder Traversal
    Leetcode Minimum Depth of Binary Tree
    Leetcode 148. Sort List
    Leetcode 61. Rotate List
    Leetcode 86. Partition List
    Leetcode 21. Merge Two Sorted Lists
    Leetcode 143. Reorder List
    J2EE项目应用开发过程中的易错点
    JNDI初认识
    奔腾的代码
  • 原文地址:https://www.cnblogs.com/xhh-lite/p/8135287.html
Copyright © 2011-2022 走看看