using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using HandyControl.Data; using HandyControl.Interactivity; using HandyControl.Tools; using HandyControl.Tools.Extension; namespace HandyControl.Controls { /// /// 页码 /// [TemplatePart(Name = ElementButtonLeft, Type = typeof(Button))] [TemplatePart(Name = ElementButtonRight, Type = typeof(Button))] [TemplatePart(Name = ElementButtonFirst, Type = typeof(RadioButton))] [TemplatePart(Name = ElementTextBlockLeft, Type = typeof(TextBlock))] [TemplatePart(Name = ElementPanelMain, Type = typeof(Panel))] [TemplatePart(Name = ElementTextBlockRight, Type = typeof(TextBlock))] [TemplatePart(Name = ElementButtonLast, Type = typeof(RadioButton))] public class Pagination : Control { #region Constants private const string ElementButtonLeft = "PART_ButtonLeft"; private const string ElementButtonRight = "PART_ButtonRight"; private const string ElementButtonFirst = "PART_ButtonFirst"; private const string ElementTextBlockLeft = "PART_TextBlockLeft"; private const string ElementPanelMain = "PART_PanelMain"; private const string ElementTextBlockRight = "PART_TextBlockRight"; private const string ElementButtonLast = "PART_ButtonLast"; #endregion Constants #region Data private Button _buttonLeft; private Button _buttonRight; private RadioButton _buttonFirst; private TextBlock _textBlockLeft; private Panel _panelMain; private TextBlock _textBlockRight; private RadioButton _buttonLast; private bool _appliedTemplate; #endregion Data #region Public Events /// /// 页面更新事件 /// public static readonly RoutedEvent PageUpdatedEvent = EventManager.RegisterRoutedEvent("PageUpdated", RoutingStrategy.Bubble, typeof(EventHandler>), typeof(Pagination)); /// /// 页面更新事件 /// public event EventHandler> PageUpdated { add => AddHandler(PageUpdatedEvent, value); remove => RemoveHandler(PageUpdatedEvent, value); } #endregion Public Events public Pagination() { CommandBindings.Add(new CommandBinding(ControlCommands.Prev, ButtonPrev_OnClick)); CommandBindings.Add(new CommandBinding(ControlCommands.Next, ButtonNext_OnClick)); CommandBindings.Add(new CommandBinding(ControlCommands.Selected, ToggleButton_OnChecked)); } #region Public Properties #region MaxPageCount /// /// 最大页数 /// public static readonly DependencyProperty MaxPageCountProperty = DependencyProperty.Register( "MaxPageCount", typeof(int), typeof(Pagination), new PropertyMetadata(1, (o, args) => { if (o is Pagination pagination && args.NewValue is int value) { if (pagination.PageIndex > pagination.MaxPageCount) { pagination.PageIndex = pagination.MaxPageCount; } pagination.Show(value > 1); pagination.Update(); } }, (o, value) => { if (!(o is Pagination)) return 1; var intValue = (int)value; if (intValue < 1) { return 1; } return intValue; })); /// /// 最大页数 /// public int MaxPageCount { get => (int)GetValue(MaxPageCountProperty); set => SetValue(MaxPageCountProperty, value); } #endregion MaxPageCount #region DataCountPerPage /// /// 每页的数据量 /// public static readonly DependencyProperty DataCountPerPageProperty = DependencyProperty.Register( "DataCountPerPage", typeof(int), typeof(Pagination), new PropertyMetadata(20, (o, args) => { if (o is Pagination pagination) { pagination.Update(); } }, (o, value) => { if (!(o is Pagination)) return 1; var intValue = (int)value; if (intValue < 1) { return 1; } return intValue; })); /// /// 每页的数据量 /// public int DataCountPerPage { get => (int)GetValue(DataCountPerPageProperty); set => SetValue(DataCountPerPageProperty, value); } #endregion #region PageIndex /// /// 当前页 /// public static readonly DependencyProperty PageIndexProperty = DependencyProperty.Register( "PageIndex", typeof(int), typeof(Pagination), new PropertyMetadata(1, (o, args) => { if (o is Pagination pagination && args.NewValue is int value) { pagination.Update(); pagination.RaiseEvent(new FunctionEventArgs(PageUpdatedEvent, pagination) { Info = value }); } }, (o, value) => { if (!(o is Pagination pagination)) return 1; var intValue = (int)value; if (intValue < 0) { return 0; } if (intValue > pagination.MaxPageCount) return pagination.MaxPageCount; return intValue; })); /// /// 当前页 /// public int PageIndex { get => (int)GetValue(PageIndexProperty); set => SetValue(PageIndexProperty, value); } #endregion PageIndex #region MaxPageInterval /// /// 表示当前选中的按钮距离左右两个方向按钮的最大间隔(4表示间隔4个按钮,如果超过则用省略号表示) /// public static readonly DependencyProperty MaxPageIntervalProperty = DependencyProperty.Register( "MaxPageInterval", typeof(int), typeof(Pagination), new PropertyMetadata(3, (o, args) => { if (o is Pagination pagination) { pagination.Update(); } }), value => { var intValue = (int)value; return intValue >= 0; }); /// /// 表示当前选中的按钮距离左右两个方向按钮的最大间隔(4表示间隔4个按钮,如果超过则用省略号表示) /// public int MaxPageInterval { get => (int)GetValue(MaxPageIntervalProperty); set => SetValue(MaxPageIntervalProperty, value); } #endregion MaxPageInterval #endregion #region Public Methods public override void OnApplyTemplate() { _appliedTemplate = false; base.OnApplyTemplate(); _buttonLeft = GetTemplateChild(ElementButtonLeft) as Button; _buttonRight = GetTemplateChild(ElementButtonRight) as Button; _buttonFirst = GetTemplateChild(ElementButtonFirst) as RadioButton; _textBlockLeft = GetTemplateChild(ElementTextBlockLeft) as TextBlock; _panelMain = GetTemplateChild(ElementPanelMain) as Panel; _textBlockRight = GetTemplateChild(ElementTextBlockRight) as TextBlock; _buttonLast = GetTemplateChild(ElementButtonLast) as RadioButton; CheckNull(); _appliedTemplate = true; Update(); } #endregion Public Methods #region Private Methods private void CheckNull() { if (_buttonLeft == null || _buttonRight == null || _buttonFirst == null || _textBlockLeft == null || _panelMain == null || _textBlockRight == null || _buttonLast == null) throw new Exception(); } /// /// 更新 /// private void Update() { if (!_appliedTemplate) return; _buttonLeft.IsEnabled = PageIndex > 1; _buttonRight.IsEnabled = PageIndex < MaxPageCount; if (MaxPageInterval == 0) { _buttonFirst.Collapse(); _buttonLast.Collapse(); _textBlockLeft.Collapse(); _textBlockRight.Collapse(); _panelMain.Children.Clear(); var selectButton = CreateButton(PageIndex); _panelMain.Children.Add(selectButton); selectButton.IsChecked = true; return; } _buttonFirst.Show(); _buttonLast.Show(); _textBlockLeft.Show(); _textBlockRight.Show(); //更新最后一页 if (MaxPageCount == 1) { _buttonLast.Collapse(); } else { _buttonLast.Show(); _buttonLast.Tag = MaxPageCount.ToString(); } //更新省略号 var right = MaxPageCount - PageIndex; var left = PageIndex - 1; _textBlockRight.Show(right > MaxPageInterval); _textBlockLeft.Show(left > MaxPageInterval); //更新中间部分 _panelMain.Children.Clear(); if (PageIndex > 1 && PageIndex < MaxPageCount) { var selectButton = CreateButton(PageIndex); _panelMain.Children.Add(selectButton); selectButton.IsChecked = true; } else if (PageIndex == 1) { _buttonFirst.IsChecked = true; } else { _buttonLast.IsChecked = true; } var sub = PageIndex; for (int i = 0; i < MaxPageInterval - 1; i++) { if (--sub > 1) { _panelMain.Children.Insert(0, CreateButton(sub)); } else { break; } } var add = PageIndex; for (int i = 0; i < MaxPageInterval - 1; i++) { if (++add < MaxPageCount) { _panelMain.Children.Add(CreateButton(add)); } else { break; } } } private void ButtonPrev_OnClick(object sender, RoutedEventArgs e) => PageIndex--; private void ButtonNext_OnClick(object sender, RoutedEventArgs e) => PageIndex++; private RadioButton CreateButton(int page) { return new RadioButton { Style = ResourceHelper.GetResource