diff --git a/src/Avalonia/HandyControlDemo_Avalonia/Data/DemoInfo.json b/src/Avalonia/HandyControlDemo_Avalonia/Data/DemoInfo.json
index cc757c13..340fe691 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/Data/DemoInfo.json
+++ b/src/Avalonia/HandyControlDemo_Avalonia/Data/DemoInfo.json
@@ -58,6 +58,7 @@
[ "UniformSpacingPanel", "UniformSpacingPanelDemo", "Brush.IncreaseHorizontalSpacing", "", "Layout" ],
[ "ProgressBar", "ProgressBarDemo", "Brush.ProgressBar", "", "Feedback" ],
[ "Rate", "RateDemo", "Brush.Favorite", "", "Feedback" ],
+ [ "Pagination", "PaginationDemo", "Brush.Paginator", "", "Navigation" ],
[ "Loading", "LoadingDemo", "Brush.Loading", "", "Feedback" ],
[ "Tag", "TagDemo", "Brush.Tag", "", "DataDisplay" ],
[ "Badge", "BadgeDemo", "Brush.CheckDot", "", "DataDisplay" ],
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Controls/PaginationDemo.axaml b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Controls/PaginationDemo.axaml
new file mode 100644
index 00000000..b3d25a70
--- /dev/null
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Controls/PaginationDemo.axaml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Controls/PaginationDemo.axaml.cs b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Controls/PaginationDemo.axaml.cs
new file mode 100644
index 00000000..48dd99a1
--- /dev/null
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Controls/PaginationDemo.axaml.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Avalonia;
+using HandyControl.Data;
+using HandyControlDemo.Data;
+
+namespace HandyControlDemo.UserControl;
+
+public partial class PaginationDemo : Avalonia.Controls.UserControl
+{
+ private readonly List _totalDataList;
+
+ public static readonly DirectProperty> DataListProperty =
+ AvaloniaProperty.RegisterDirect>(nameof(DataList), o => o.DataList);
+
+ public PaginationDemo()
+ {
+ InitializeComponent();
+
+ DataContext = this;
+
+ _totalDataList = BuildDataList(100);
+ DataList = new ObservableCollection();
+ LoadPage(1, 10);
+ }
+
+ public ObservableCollection DataList { get; }
+
+ private void Pagination_OnPageUpdated(object? sender, FunctionEventArgs e)
+ {
+ var page = Math.Max(e.Info, 1);
+ LoadPage(page, 10);
+ }
+
+ private void LoadPage(int page, int pageSize)
+ {
+ DataList.Clear();
+ foreach (var item in _totalDataList.Skip((page - 1) * pageSize).Take(pageSize))
+ {
+ DataList.Add(item);
+ }
+ }
+
+ private static List BuildDataList(int total)
+ {
+ var list = new List();
+ for (var i = 1; i <= total; i++)
+ {
+ list.Add(new DemoDataModel
+ {
+ Index = i,
+ Name = $"Name{i}",
+ IsSelected = i % 2 == 0,
+ Type = (DemoType)(i % 6 + 1),
+ ImgPath = string.Empty,
+ Remark = new string((i % 10).ToString()[0], 10)
+ });
+ }
+
+ return list;
+ }
+}
diff --git a/src/Avalonia/HandyControl_Avalonia/Controls/Other/Pagination.cs b/src/Avalonia/HandyControl_Avalonia/Controls/Other/Pagination.cs
new file mode 100644
index 00000000..c24950d6
--- /dev/null
+++ b/src/Avalonia/HandyControl_Avalonia/Controls/Other/Pagination.cs
@@ -0,0 +1,389 @@
+using System;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Metadata;
+using Avalonia.Controls.Primitives;
+using Avalonia.Interactivity;
+using Avalonia.Styling;
+using HandyControl.Data;
+
+namespace HandyControl.Controls;
+
+[TemplatePart(Name = ElementButtonLeft, Type = typeof(Button))]
+[TemplatePart(Name = ElementButtonRight, Type = typeof(Button))]
+[TemplatePart(Name = ElementButtonFirst, Type = typeof(RadioButton))]
+[TemplatePart(Name = ElementMoreLeft, Type = typeof(Control))]
+[TemplatePart(Name = ElementPanelMain, Type = typeof(Panel))]
+[TemplatePart(Name = ElementMoreRight, Type = typeof(Control))]
+[TemplatePart(Name = ElementButtonLast, Type = typeof(RadioButton))]
+[TemplatePart(Name = ElementJump, Type = typeof(NumericUpDown))]
+[TemplatePart(Name = ElementButtonJump, Type = typeof(Button))]
+public class Pagination : TemplatedControl
+{
+ private const string ElementButtonLeft = "PART_ButtonLeft";
+ private const string ElementButtonRight = "PART_ButtonRight";
+ private const string ElementButtonFirst = "PART_ButtonFirst";
+ private const string ElementMoreLeft = "PART_MoreLeft";
+ private const string ElementPanelMain = "PART_PanelMain";
+ private const string ElementMoreRight = "PART_MoreRight";
+ private const string ElementButtonLast = "PART_ButtonLast";
+ private const string ElementJump = "PART_Jump";
+ private const string ElementButtonJump = "PART_ButtonJump";
+
+ public static readonly RoutedEvent> PageUpdatedEvent =
+ RoutedEvent.Register>(nameof(PageUpdated), RoutingStrategies.Bubble);
+
+ public static readonly StyledProperty MaxPageCountProperty =
+ AvaloniaProperty.Register(nameof(MaxPageCount), 1);
+
+ public static readonly StyledProperty DataCountPerPageProperty =
+ AvaloniaProperty.Register(nameof(DataCountPerPage), 20);
+
+ public static readonly StyledProperty PageIndexProperty =
+ AvaloniaProperty.Register(nameof(PageIndex), 1);
+
+ public static readonly StyledProperty MaxPageIntervalProperty =
+ AvaloniaProperty.Register(nameof(MaxPageInterval), 3);
+
+ public static readonly StyledProperty IsJumpEnabledProperty =
+ AvaloniaProperty.Register(nameof(IsJumpEnabled));
+
+ public static readonly StyledProperty AutoHidingProperty =
+ AvaloniaProperty.Register(nameof(AutoHiding), true);
+
+ public static readonly StyledProperty PaginationButtonThemeProperty =
+ AvaloniaProperty.Register(nameof(PaginationButtonTheme));
+
+ private readonly string _groupName = Guid.NewGuid().ToString("N");
+
+ private Button? _buttonLeft;
+ private Button? _buttonRight;
+ private RadioButton? _buttonFirst;
+ private Control? _moreLeft;
+ private Panel? _panelMain;
+ private Control? _moreRight;
+ private RadioButton? _buttonLast;
+ private NumericUpDown? _jumpNumericUpDown;
+ private Button? _buttonJump;
+
+ private bool _appliedTemplate;
+ private bool _isUpdating;
+
+ static Pagination()
+ {
+ MaxPageCountProperty.Changed.AddClassHandler((pagination, e) => pagination.OnMaxPageCountChanged(e));
+ PageIndexProperty.Changed.AddClassHandler((pagination, e) => pagination.OnPageIndexChanged(e));
+ MaxPageIntervalProperty.Changed.AddClassHandler((pagination, _) => pagination.Update());
+ DataCountPerPageProperty.Changed.AddClassHandler((pagination, _) => pagination.Update());
+ AutoHidingProperty.Changed.AddClassHandler((pagination, _) => pagination.OnAutoHidingChanged());
+ }
+
+ public event EventHandler> PageUpdated
+ {
+ add => AddHandler(PageUpdatedEvent, value);
+ remove => RemoveHandler(PageUpdatedEvent, value);
+ }
+
+ public int MaxPageCount
+ {
+ get => GetValue(MaxPageCountProperty);
+ set => SetValue(MaxPageCountProperty, value);
+ }
+
+ public int DataCountPerPage
+ {
+ get => GetValue(DataCountPerPageProperty);
+ set => SetValue(DataCountPerPageProperty, value);
+ }
+
+ public int PageIndex
+ {
+ get => GetValue(PageIndexProperty);
+ set => SetValue(PageIndexProperty, value);
+ }
+
+ public int MaxPageInterval
+ {
+ get => GetValue(MaxPageIntervalProperty);
+ set => SetValue(MaxPageIntervalProperty, value);
+ }
+
+ public bool IsJumpEnabled
+ {
+ get => GetValue(IsJumpEnabledProperty);
+ set => SetValue(IsJumpEnabledProperty, value);
+ }
+
+ public bool AutoHiding
+ {
+ get => GetValue(AutoHidingProperty);
+ set => SetValue(AutoHidingProperty, value);
+ }
+
+ public ControlTheme? PaginationButtonTheme
+ {
+ get => GetValue(PaginationButtonThemeProperty);
+ set => SetValue(PaginationButtonThemeProperty, value);
+ }
+
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ _appliedTemplate = false;
+
+ if (_buttonLeft != null)
+ {
+ _buttonLeft.Click -= ButtonPrevOnClick;
+ }
+
+ if (_buttonRight != null)
+ {
+ _buttonRight.Click -= ButtonNextOnClick;
+ }
+
+ if (_buttonFirst != null)
+ {
+ _buttonFirst.Checked -= ToggleButtonOnChecked;
+ }
+
+ if (_buttonLast != null)
+ {
+ _buttonLast.Checked -= ToggleButtonOnChecked;
+ }
+
+ if (_buttonJump != null)
+ {
+ _buttonJump.Click -= ButtonJumpOnClick;
+ }
+
+ base.OnApplyTemplate(e);
+
+ _buttonLeft = e.NameScope.Find