WPF管理系統自定義分頁控件 - WPF特工隊內部資料

  最近作一個演示的管理系統項目,須要用到分頁控件,在網上找了不少,依然找到與UI模版匹配的,最後乾脆本身寫一個。express

  分頁控件分析:app

    一、分頁控件分簡單顯示和複雜顯示兩種;ide

    二、包含上一頁、下一頁以及頁碼明細邏輯處理;this

    三、頁碼總數小於7時顯示默認顯示,大於7時切換複雜顯示;spa

    四、頁碼數、索引、總條數計算等;code

 

  先來一張效果圖:  component

  

 

  

 

  啥也不說了直接上代碼orm

  MISPager.xaml部分xml

<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部分blog

  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頁,顯示一、二、三、四、五、六、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              * 一、默認分頁的按鈕爲7個
319              * 二、當分頁總數小於等於7時,直接顯示1-7個分頁按鈕
320              * 三、當分頁總數大於7時,顯示當時爲一、二、三、四、五、...、999(999爲總頁數)
321              * 四、
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 }
相關文章
相關標籤/搜索