WPF实现列表分页控件的示例代码

这篇文章主要为大家详细介绍了如何利用WPF实现列表分页控件,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下

WPF 之列表分页控件

框架使用大于等于.NET40

Visual Studio 2022

项目使用 MIT 开源许可协议。

新建Pagination自定义控件继承自Control

正常模式分页 在外部套Grid分为0 - 5列:

  • Grid.Column 0 总页数共多少300条。
  • Grid.Column 1 输入每页显示多少10条。
  • Grid.Column 2 上一页按钮。
  • Grid.Column 3 所有页码按钮此处使用ListBox
  • Grid.Column 4 下一页按钮。
  • Grid.Column 5 跳转页1码输入框。

精简模式分页 在外部套Grid分为0 - 9列:

  • Grid.Column 0 总页数共多少300条。
  • Grid.Column 2 输入每页显示多少10条。
  • Grid.Column 3 条 / 页
  • Grid.Column 5 上一页按钮。
  • Grid.Column 7 跳转页1码输入框。
  • Grid.Column 9 下一页按钮。

每页显示与跳转页码数控制只允许输入数字,不允许粘贴。

实现代码

1) Pagination.cs 如下:

using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using WPFDevelopers.Helpers; namespace WPFDevelopers.Controls {     [TemplatePart(Name = CountPerPageTextBoxTemplateName, Type = typeof(TextBox))]     [TemplatePart(Name = JustPageTextBoxTemplateName, Type = typeof(TextBox))]     [TemplatePart(Name = ListBoxTemplateName, Type = typeof(ListBox))]     public class Pagination : Control     {         private const string CountPerPageTextBoxTemplateName = "PART_CountPerPageTextBox";         private const string JustPageTextBoxTemplateName = "PART_JumpPageTextBox";         private const string ListBoxTemplateName = "PART_ListBox";         private const string Ellipsis = "···";         private static readonly Type _typeofSelf = typeof(Pagination);         private TextBox _countPerPageTextBox;         private TextBox _jumpPageTextBox;         private ListBox _listBox;         static Pagination()         {             InitializeCommands();             DefaultStyleKeyProperty.OverrideMetadata(_typeofSelf, new FrameworkPropertyMetadata(_typeofSelf));         }         #region Override         public override void OnApplyTemplate()         {             base.OnApplyTemplate();             UnsubscribeEvents();             _countPerPageTextBox = GetTemplateChild(CountPerPageTextBoxTemplateName) as TextBox;             if (_countPerPageTextBox != null)             {                 _countPerPageTextBox.ContextMenu = null;                 _countPerPageTextBox.PreviewTextInput += _countPerPageTextBox_PreviewTextInput;                 _countPerPageTextBox.PreviewKeyDown += _countPerPageTextBox_PreviewKeyDown;             }             _jumpPageTextBox = GetTemplateChild(JustPageTextBoxTemplateName) as TextBox;             if (_jumpPageTextBox != null)             {                 _jumpPageTextBox.ContextMenu = null;                 _jumpPageTextBox.PreviewTextInput += _countPerPageTextBox_PreviewTextInput;                 _jumpPageTextBox.PreviewKeyDown += _countPerPageTextBox_PreviewKeyDown;             }             _listBox = GetTemplateChild(ListBoxTemplateName) as ListBox;             Init();             SubscribeEvents();         }         private void _countPerPageTextBox_PreviewKeyDown(object sender, KeyEventArgs e)         {             if (Key.Space == e.Key                 ||                 Key.V == e.Key                 && e.KeyboardDevice.Modifiers == ModifierKeys.Control)                 e.Handled = true;         }         private void _countPerPageTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)         {             e.Handled = ControlsHelper.IsNumber(e.Text);         }         #endregion         #region Command         private static void InitializeCommands()         {             PrevCommand = new RoutedCommand("Prev", _typeofSelf);             NextCommand = new RoutedCommand("Next", _typeofSelf);             CommandManager.RegisterClassCommandBinding(_typeofSelf,                 new CommandBinding(PrevCommand, OnPrevCommand, OnCanPrevCommand));             CommandManager.RegisterClassCommandBinding(_typeofSelf,                 new CommandBinding(NextCommand, OnNextCommand, OnCanNextCommand));         }         public static RoutedCommand PrevCommand { get; private set; }         public static RoutedCommand NextCommand { get; private set; }         private static void OnPrevCommand(object sender, RoutedEventArgs e)         {             var ctrl = sender as Pagination;             ctrl.Current--;         }         private static void OnCanPrevCommand(object sender, CanExecuteRoutedEventArgs e)         {             var ctrl = sender as Pagination;             e.CanExecute = ctrl.Current > 1;         }         private static void OnNextCommand(object sender, RoutedEventArgs e)         {             var ctrl = sender as Pagination;             ctrl.Current++;         }         private static void OnCanNextCommand(object sender, CanExecuteRoutedEventArgs e)         {             var ctrl = sender as Pagination;             e.CanExecute = ctrl.Current < ctrl.PageCount;         }         #endregion         #region Properties         private static readonly DependencyPropertyKey PagesPropertyKey =             DependencyProperty.RegisterReadOnly("Pages", typeof(IEnumerable), _typeofSelf,                 new PropertyMetadata(null));         public static readonly DependencyProperty PagesProperty = PagesPropertyKey.DependencyProperty;         public IEnumerable Pages => (IEnumerable) GetValue(PagesProperty);         private static readonly DependencyPropertyKey PageCountPropertyKey =             DependencyProperty.RegisterReadOnly("PageCount", typeof(int), _typeofSelf,                 new PropertyMetadata(1, OnPageCountPropertyChanged));         public static readonly DependencyProperty PageCountProperty = PageCountPropertyKey.DependencyProperty;         public int PageCount => (int) GetValue(PageCountProperty);         private static void OnPageCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)         {             var ctrl = d as Pagination;             var pageCount = (int) e.NewValue;             /*             if (ctrl._jumpPageTextBox != null)                 ctrl._jumpPageTextBox.Maximum = pageCount;             */         }         public static readonly DependencyProperty IsLiteProperty =             DependencyProperty.Register("IsLite", typeof(bool), _typeofSelf, new PropertyMetadata(false));         public bool IsLite         {             get => (bool) GetValue(IsLiteProperty);             set => SetValue(IsLiteProperty, value);         }         public static readonly DependencyProperty CountProperty = DependencyProperty.Register("Count", typeof(int),             _typeofSelf, new PropertyMetadata(0, OnCountPropertyChanged, CoerceCount));         public int Count         {             get => (int) GetValue(CountProperty);             set => SetValue(CountProperty, value);         }         private static object CoerceCount(DependencyObject d, object value)         {             var count = (int) value;             return Math.Max(count, 0);         }         private static void OnCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)         {             var ctrl = d as Pagination;             var count = (int) e.NewValue;             ctrl.SetValue(PageCountPropertyKey, (int) Math.Ceiling(count * 1.0 / ctrl.CountPerPage));             ctrl.UpdatePages();         }         public static readonly DependencyProperty CountPerPageProperty = DependencyProperty.Register("CountPerPage",             typeof(int), _typeofSelf, new PropertyMetadata(50, OnCountPerPagePropertyChanged, CoerceCountPerPage));         public int CountPerPage         {             get => (int) GetValue(CountPerPageProperty);             set => SetValue(CountPerPageProperty, value);         }         private static object CoerceCountPerPage(DependencyObject d, object value)         {             var countPerPage = (int) value;             return Math.Max(countPerPage, 1);         }         private static void OnCountPerPagePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)         {             var ctrl = d as Pagination;             var countPerPage = (int) e.NewValue;             if (ctrl._countPerPageTextBox != null)                 ctrl._countPerPageTextBox.Text = countPerPage.ToString();             ctrl.SetValue(PageCountPropertyKey, (int) Math.Ceiling(ctrl.Count * 1.0 / countPerPage));             if (ctrl.Current != 1)                 ctrl.Current = 1;             else                 ctrl.UpdatePages();         }         public static readonly DependencyProperty CurrentProperty = DependencyProperty.Register("Current", typeof(int),             _typeofSelf, new PropertyMetadata(1, OnCurrentPropertyChanged, CoerceCurrent));         public int Current         {             get => (int) GetValue(CurrentProperty);             set => SetValue(CurrentProperty, value);         }         private static object CoerceCurrent(DependencyObject d, object value)         {             var current = (int) value;             var ctrl = d as Pagination;             return Math.Max(current, 1);         }         private static void OnCurrentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)         {             var ctrl = d as Pagination;             var current = (int) e.NewValue;             if (ctrl._listBox != null)                 ctrl._listBox.SelectedItem = current.ToString();             if (ctrl._jumpPageTextBox != null)                 ctrl._jumpPageTextBox.Text = current.ToString();             ctrl.UpdatePages();         }         #endregion         #region Event         ///          ///     分页         ///          private void OnCountPerPageTextBoxChanged(object sender, TextChangedEventArgs e)         {             if (int.TryParse(_countPerPageTextBox.Text, out var _ountPerPage))                 CountPerPage = _ountPerPage;         }         ///          ///     跳转页         ///          private void OnJumpPageTextBoxChanged(object sender, TextChangedEventArgs e)         {             if (int.TryParse(_jumpPageTextBox.Text, out var _current))                 Current = _current;         }         ///          ///     选择页         ///          private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)         {             if (_listBox.SelectedItem == null)                 return;             Current = int.Parse(_listBox.SelectedItem.ToString());         }         #endregion         #region Private         private void Init()         {             SetValue(PageCountPropertyKey, (int) Math.Ceiling(Count * 1.0 / CountPerPage));             _jumpPageTextBox.Text = Current.ToString();             //_jumpPageTextBox.Maximum = PageCount;             _countPerPageTextBox.Text = CountPerPage.ToString();             if (_listBox != null)                 _listBox.SelectedItem = Current.ToString();         }         private void UnsubscribeEvents()         {             if (_countPerPageTextBox != null)                 _countPerPageTextBox.TextChanged -= OnCountPerPageTextBoxChanged;             if (_jumpPageTextBox != null)                 _jumpPageTextBox.TextChanged -= OnJumpPageTextBoxChanged;             if (_listBox != null)                 _listBox.SelectionChanged -= OnSelectionChanged;         }         private void SubscribeEvents()         {             if (_countPerPageTextBox != null)                 _countPerPageTextBox.TextChanged += OnCountPerPageTextBoxChanged;             if (_jumpPageTextBox != null)                 _jumpPageTextBox.TextChanged += OnJumpPageTextBoxChanged;             if (_listBox != null)                 _listBox.SelectionChanged += OnSelectionChanged;         }         private void UpdatePages()         {             SetValue(PagesPropertyKey, GetPagers(Count, Current));             if (_listBox != null && _listBox.SelectedItem == null)                 _listBox.SelectedItem = Current.ToString();         }         private IEnumerable GetPagers(int count, int current)         {             if (count == 0)                 return null;             if (PageCount <= 7)                 return Enumerable.Range(1, PageCount).Select(p => p.ToString()).ToArray();             if (current <= 4)                 return new[] {"1", "2", "3", "4", "5", Ellipsis, PageCount.ToString()};             if (current >= PageCount - 3)                 return new[]                 {                     "1", Ellipsis, (PageCount - 4).ToString(), (PageCount - 3).ToString(), (PageCount - 2).ToString(),                     (PageCount - 1).ToString(), PageCount.ToString()                 };             return new[]             {                 "1", Ellipsis, (current - 1).ToString(), current.ToString(), (current + 1).ToString(), Ellipsis,                 PageCount.ToString()             };         }         #endregion     } } 

2) Pagination.xaml 如下:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

3) 创建PaginationExampleVM.cs如下:

using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace WPFDevelopers.Samples.ViewModels {     public class PaginationExampleVM : ViewModelBase     {         private List _sourceList = new List();         public PaginationExampleVM()         {             _sourceList.AddRange(Enumerable.Range(1, 300));             Count = 300;             CurrentPageChanged();         }         public ObservableCollection PaginationCollection { get; set; } = new ObservableCollection();         private int _count;         public int Count         {             get { return _count; }             set { _count = value;  this.NotifyPropertyChange("Count"); CurrentPageChanged(); }         }         private int _countPerPage = 10;         public int CountPerPage         {             get { return _countPerPage; }             set { _countPerPage = value; this.NotifyPropertyChange("CountPerPage"); CurrentPageChanged(); }         }         private int _current = 1;         public int Current         {             get { return _current; }             set { _current = value; this.NotifyPropertyChange("Current"); CurrentPageChanged(); }         }         private void CurrentPageChanged()         {             PaginationCollection.Clear();             foreach (var i in _sourceList.Skip((Current - 1) * CountPerPage).Take(CountPerPage))             {                 PaginationCollection.Add(i);             }         }     } }

4) 使用 PaginationExample.xaml 如下:

                                                                                                                                                                                                                                                     

5) 使用PaginationExample.xaml.cs如下:

using System.Windows.Controls; using WPFDevelopers.Samples.ViewModels; namespace WPFDevelopers.Samples.ExampleViews {     ///      /// PaginationExample.xaml 的交互逻辑     ///      public partial class PaginationExample : UserControl     {         public PaginationExampleVM NormalPaginationViewModel { get; set; } = new PaginationExampleVM();         public PaginationExampleVM LitePaginationViewModel { get; set; } = new PaginationExampleVM();         public PaginationExample()         {             InitializeComponent();             this.DataContext = this;         }     } }

实现效果

以上就是WPF实现列表分页控件的示例代码的详细内容,更多关于WPF列表分页控件的资料请关注0133技术站其它相关文章!

以上就是WPF实现列表分页控件的示例代码的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 其他教程