WPF管理系统自定义分页控件 - WPF特工队内部资料

Posted lonelyxmas

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF管理系统自定义分页控件 - WPF特工队内部资料相关的知识,希望对你有一定的参考价值。

原文:WPF管理系统自定义分页控件 - 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 }

 

以上是关于WPF管理系统自定义分页控件 - WPF特工队内部资料的主要内容,如果未能解决你的问题,请参考以下文章

WPF报表自定义通用可筛选列头-WPF特工队内部资料

C# wpf 如何实现自定义控件,布局时,大小发生变化,内部绘制的曲线跟随变化?

WPF 之列表分页控件

wpf中动态添加的自定义控件过宽,不能完全显示,怎么办

wpf 重新加载自定义控件出现异常

WPF 仿语音播放 自定义控件