From 74ad5f4111105d2e2ab77a1814cc2b21b0db7957 Mon Sep 17 00:00:00 2001 From: Soar360 Date: Sat, 23 Mar 2024 14:46:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BA=20Pagination=20=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20CurrentPageChanged=20=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E4=B8=BA=20Pagination=20=E6=8E=A7=E4=BB=B6=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=20Command=20=E5=B1=9E=E6=80=A7=20=E4=B8=BA=20Pagination=20?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E5=A2=9E=E5=8A=A0=20Command=20=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E7=9A=84=E4=BD=BF=E7=94=A8=20Demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/Ursa.Demo/Pages/PaginationDemo.axaml | 2 + .../ViewModels/PaginationDemoViewModel.cs | 16 +++- src/Ursa/Controls/Pagination/Pagination.cs | 88 +++++++++++++++---- 3 files changed, 86 insertions(+), 20 deletions(-) diff --git a/demo/Ursa.Demo/Pages/PaginationDemo.axaml b/demo/Ursa.Demo/Pages/PaginationDemo.axaml index 602c2da..77b537e 100644 --- a/demo/Ursa.Demo/Pages/PaginationDemo.axaml +++ b/demo/Ursa.Demo/Pages/PaginationDemo.axaml @@ -24,6 +24,8 @@ PageSizeOptions="10, 20, 50, 100" ShowQuickJump="{Binding #quickJumperSelector.IsChecked}" ShowPageSizeSelector="{Binding #pageSizeSelector.IsChecked}" + Command="{Binding LoadPageCommand}" + CommandParameter="{Binding $self.CurrentPage}" TotalCount="600" /> diff --git a/demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs index 55bb942..a64dc9c 100644 --- a/demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs @@ -1,11 +1,25 @@ using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Windows.Input; using Avalonia.Collections; using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; namespace Ursa.Demo.ViewModels; -public class PaginationDemoViewModel: ViewModelBase +public class PaginationDemoViewModel : ViewModelBase { public AvaloniaList PageSizes { get; set; } = new() { 10, 20, 50, 100 }; + + public ICommand LoadPageCommand { get; } + public PaginationDemoViewModel() + { + this.LoadPageCommand = new RelayCommand(LoadPage); + } + + private void LoadPage(int? pageIndex) + { + Debug.WriteLine($"Loading page {pageIndex}"); + } } \ No newline at end of file diff --git a/src/Ursa/Controls/Pagination/Pagination.cs b/src/Ursa/Controls/Pagination/Pagination.cs index a5bde53..78b3793 100644 --- a/src/Ursa/Controls/Pagination/Pagination.cs +++ b/src/Ursa/Controls/Pagination/Pagination.cs @@ -7,6 +7,7 @@ using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Styling; using Irihi.Avalonia.Shared.Helpers; +using System.Windows.Input; namespace Ursa.Controls; @@ -30,16 +31,53 @@ public class Pagination: TemplatedControl private StackPanel? _buttonPanel; private readonly PaginationButton[] _buttons = new PaginationButton[7]; private NumericIntUpDown? _quickJumpInput; - + public static readonly StyledProperty CurrentPageProperty = AvaloniaProperty.Register( nameof(CurrentPage)); - + public int? CurrentPage { get => GetValue(CurrentPageProperty); set => SetValue(CurrentPageProperty, value); } + private void OnCurrentPageChanged(AvaloniaPropertyChangedEventArgs args) + { + int? oldValue = args.GetOldValue(); + int? newValue = args.GetNewValue(); + var e = new ValueChangedEventArgs(CurrentPageChangedEvent, oldValue, newValue); + RaiseEvent(e); + } + + public static readonly RoutedEvent> CurrentPageChangedEvent = + RoutedEvent.Register>(nameof(CurrentPageChanged), RoutingStrategies.Bubble); + + /// + /// Raised when the changes. + /// + public event EventHandler>? CurrentPageChanged + { + add => AddHandler(CurrentPageChangedEvent, value); + remove => RemoveHandler(CurrentPageChangedEvent, value); + } + + public static readonly StyledProperty CommandProperty = AvaloniaProperty.Register( + nameof(Command)); + + public ICommand? Command + { + get => GetValue(CommandProperty); + set => SetValue(CommandProperty, value); + } + + public static readonly StyledProperty CommandParameterProperty = AvaloniaProperty.Register(nameof(CommandParameter)); + + public object? CommandParameter + { + get => this.GetValue(CommandParameterProperty); + set => this.SetValue(CommandParameterProperty, value); + } + public static readonly StyledProperty TotalCountProperty = AvaloniaProperty.Register( nameof(TotalCount)); @@ -54,7 +92,7 @@ public class Pagination: TemplatedControl public static readonly StyledProperty PageSizeProperty = AvaloniaProperty.Register( nameof(PageSize), defaultValue: 10); - + /// /// Page size. /// @@ -107,7 +145,7 @@ public class Pagination: TemplatedControl public static readonly StyledProperty ShowQuickJumpProperty = AvaloniaProperty.Register( nameof(ShowQuickJump)); - + public bool ShowQuickJump { get => GetValue(ShowQuickJumpProperty); @@ -116,9 +154,11 @@ public class Pagination: TemplatedControl static Pagination() { - PageSizeProperty.Changed.AddClassHandler((pagination, args)=>pagination.OnPageSizeChanged(args)); + PageSizeProperty.Changed.AddClassHandler((pagination, args) => pagination.OnPageSizeChanged(args)); CurrentPageProperty.Changed.AddClassHandler((pagination, args) => pagination.UpdateButtonsByCurrentPage(args.NewValue.Value)); + CurrentPageProperty.Changed.AddClassHandler((pagination, args) => + pagination.OnCurrentPageChanged(args)); TotalCountProperty.Changed.AddClassHandler((pagination, args) => pagination.UpdateButtonsByCurrentPage(pagination.CurrentPage)); } @@ -142,19 +182,19 @@ public class Pagination: TemplatedControl protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); - + Button.ClickEvent.AddHandler(OnButtonClick, _previousButton, _nextButton); _previousButton = e.NameScope.Find(PART_PreviousButton); _nextButton = e.NameScope.Find(PART_NextButton); _buttonPanel = e.NameScope.Find(PART_ButtonPanel); Button.ClickEvent.AddHandler(OnButtonClick, _previousButton, _nextButton); - + KeyDownEvent.RemoveHandler(OnQuickJumpInputKeyDown, _quickJumpInput); LostFocusEvent.RemoveHandler(OnQuickJumpInputLostFocus, _quickJumpInput); _quickJumpInput = e.NameScope.Find(PART_QuickJumpInput); KeyDownEvent.AddHandler(OnQuickJumpInputKeyDown, _quickJumpInput); LostFocusEvent.AddHandler(OnQuickJumpInputLostFocus, _quickJumpInput); - + InitializePanelButtons(); UpdateButtonsByCurrentPage(0); } @@ -166,12 +206,12 @@ public class Pagination: TemplatedControl SyncQuickJumperValue(); } } - + private void OnQuickJumpInputLostFocus(object sender, RoutedEventArgs e) { SyncQuickJumperValue(); } - + private void SyncQuickJumperValue() { if (_quickJumpInput is null) return; @@ -180,12 +220,14 @@ public class Pagination: TemplatedControl value = Clamp(value.Value, 1, PageCount); SetCurrentValue(CurrentPageProperty, value); _quickJumpInput?.SetCurrentValue(NumericIntUpDown.ValueProperty, null); + InvokeCommand(); } private void OnButtonClick(object? sender, RoutedEventArgs e) { var diff = Equals(sender, _previousButton) ? -1 : 1; AddCurrentPage(diff); + InvokeCommand(); } private void InitializePanelButtons() @@ -218,20 +260,21 @@ public class Pagination: TemplatedControl CurrentPage = pageButton.Page; } } + InvokeCommand(); } private void AddCurrentPage(int pageChange) { int newValue = (CurrentPage ?? 0) + pageChange; newValue = Clamp(newValue, 1, PageCount); - ; SetCurrentValue(CurrentPageProperty, newValue); + SetCurrentValue(CurrentPageProperty, newValue); } - + private int Clamp(int value, int min, int max) { return value < min ? min : value > max ? max : value; } - + /// /// Update Button Content and Visibility by current page. /// @@ -256,7 +299,7 @@ public class Pagination: TemplatedControl if (i < pageCount) { _buttons[i].IsVisible = true; - _buttons[i].SetStatus(i + 1, i+1 == CurrentPage, false, false); + _buttons[i].SetStatus(i + 1, i + 1 == CurrentPage, false, false); } else { @@ -277,21 +320,21 @@ public class Pagination: TemplatedControl _buttons[4].Page = mid + 1; _buttons[0].Page = 1; _buttons[6].Page = pageCount; - if(mid>4) + if (mid > 4) { _buttons[1].SetStatus(-1, false, true, false); } else { - _buttons[1].SetStatus(mid-2, false, false, false); + _buttons[1].SetStatus(mid - 2, false, false, false); } - if(mid 1; + if (_previousButton != null) _previousButton.IsEnabled = (CurrentPage ?? int.MaxValue) > 1; if (_nextButton != null) _nextButton.IsEnabled = (CurrentPage ?? 0) < PageCount; } + private void InvokeCommand() + { + if (this.Command != null && this.Command.CanExecute(this.CommandParameter)) + { + this.Command.Execute(this.CommandParameter); + } + } } \ No newline at end of file