feat: WIP: add template.
This commit is contained in:
18
demo/Ursa.Demo/Pages/PaginationDemo.axaml
Normal file
18
demo/Ursa.Demo/Pages/PaginationDemo.axaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<UserControl
|
||||||
|
x:Class="Ursa.Demo.Pages.PaginationDemo"
|
||||||
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:u="https://irihi.tech/ursa"
|
||||||
|
xmlns:viewModels="clr-namespace:Ursa.Demo.ViewModels"
|
||||||
|
d:DesignHeight="450"
|
||||||
|
d:DesignWidth="800"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<Design.DataContext>
|
||||||
|
<viewModels:PaginationDemoViewModel />
|
||||||
|
</Design.DataContext>
|
||||||
|
<StackPanel>
|
||||||
|
<u:Pagination PageSizeOptions="{Binding PageSizes}" TotalCount="300" />
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
15
demo/Ursa.Demo/Pages/PaginationDemo.axaml.cs
Normal file
15
demo/Ursa.Demo/Pages/PaginationDemo.axaml.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Ursa.Demo.ViewModels;
|
||||||
|
|
||||||
|
namespace Ursa.Demo.Pages;
|
||||||
|
|
||||||
|
public partial class PaginationDemo : UserControl
|
||||||
|
{
|
||||||
|
public PaginationDemo()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.DataContext = new PaginationDemoViewModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs
Normal file
10
demo/Ursa.Demo/ViewModels/PaginationDemoViewModel.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using Avalonia.Collections;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
namespace Ursa.Demo.ViewModels;
|
||||||
|
|
||||||
|
public class PaginationDemoViewModel: ObservableObject
|
||||||
|
{
|
||||||
|
public AvaloniaList<int> PageSizes { get; set; } = new() { 10, 20, 50, 100 };
|
||||||
|
}
|
||||||
@@ -35,6 +35,9 @@
|
|||||||
<TabItem Header="IPv4Box">
|
<TabItem Header="IPv4Box">
|
||||||
<pages:IPv4BoxDemo />
|
<pages:IPv4BoxDemo />
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
<TabItem Header="Pagination">
|
||||||
|
<pages:PaginationDemo />
|
||||||
|
</TabItem>
|
||||||
<TabItem Header="Timeline">
|
<TabItem Header="Timeline">
|
||||||
<pages:TimelineDemo />
|
<pages:TimelineDemo />
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|||||||
22
src/Ursa.Themes.Semi/Controls/Pagination.axaml
Normal file
22
src/Ursa.Themes.Semi/Controls/Pagination.axaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:u="https://irihi.tech/ursa">
|
||||||
|
<!-- Add Resources Here -->
|
||||||
|
<ControlTheme x:Key="{x:Type u:Pagination}" TargetType="u:Pagination">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate TargetType="u:Pagination">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Button Name="{x:Static u:Pagination.PART_PreviousButton}" Content="<" />
|
||||||
|
<Button Name="{x:Static u:Pagination.PART_NextButton}" Content=">" />
|
||||||
|
<StackPanel Name="{x:Static u:Pagination.PART_ButtonPanel}" Orientation="Horizontal" />
|
||||||
|
<ComboBox
|
||||||
|
Name="{x:Static u:Pagination.PART_SizeChangerComboBox}"
|
||||||
|
ItemsSource="{TemplateBinding PageSizeOptions}"
|
||||||
|
SelectedItem="{TemplateBinding PageSize,
|
||||||
|
Mode=TwoWay}" />
|
||||||
|
</StackPanel>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
</ControlTheme>
|
||||||
|
</ResourceDictionary>
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
<ResourceInclude Source="Banner.axaml" />
|
<ResourceInclude Source="Banner.axaml" />
|
||||||
<ResourceInclude Source="Divider.axaml" />
|
<ResourceInclude Source="Divider.axaml" />
|
||||||
<ResourceInclude Source="IPv4Box.axaml" />
|
<ResourceInclude Source="IPv4Box.axaml" />
|
||||||
|
<ResourceInclude Source="Pagination.axaml" />
|
||||||
<ResourceInclude Source="Timeline.axaml" />
|
<ResourceInclude Source="Timeline.axaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Metadata;
|
using Avalonia.Controls.Metadata;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
@@ -10,14 +11,17 @@ namespace Ursa.Controls;
|
|||||||
[TemplatePart(PART_PreviousButton, typeof(Button))]
|
[TemplatePart(PART_PreviousButton, typeof(Button))]
|
||||||
[TemplatePart(PART_NextButton, typeof(Button))]
|
[TemplatePart(PART_NextButton, typeof(Button))]
|
||||||
[TemplatePart(PART_ButtonPanel, typeof(StackPanel))]
|
[TemplatePart(PART_ButtonPanel, typeof(StackPanel))]
|
||||||
|
[TemplatePart(PART_SizeChangerComboBox, typeof(ComboBox))]
|
||||||
public class Pagination: TemplatedControl
|
public class Pagination: TemplatedControl
|
||||||
{
|
{
|
||||||
public const string PART_PreviousButton = "PART_PreviousButton";
|
public const string PART_PreviousButton = "PART_PreviousButton";
|
||||||
public const string PART_NextButton = "PART_NextButton";
|
public const string PART_NextButton = "PART_NextButton";
|
||||||
public const string PART_ButtonPanel = "PART_ButtonPanel";
|
public const string PART_ButtonPanel = "PART_ButtonPanel";
|
||||||
|
public const string PART_SizeChangerComboBox = "PART_SizeChangerComboBox";
|
||||||
private Button? _previousButton;
|
private Button? _previousButton;
|
||||||
private Button? _nextButton;
|
private Button? _nextButton;
|
||||||
private StackPanel? _buttonPanel;
|
private StackPanel? _buttonPanel;
|
||||||
|
private ComboBox? _sizeChangerComboBox;
|
||||||
|
|
||||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -27,8 +31,11 @@ public class Pagination: TemplatedControl
|
|||||||
_previousButton = e.NameScope.Find<Button>(PART_PreviousButton);
|
_previousButton = e.NameScope.Find<Button>(PART_PreviousButton);
|
||||||
_nextButton = e.NameScope.Find<Button>(PART_NextButton);
|
_nextButton = e.NameScope.Find<Button>(PART_NextButton);
|
||||||
_buttonPanel = e.NameScope.Find<StackPanel>(PART_ButtonPanel);
|
_buttonPanel = e.NameScope.Find<StackPanel>(PART_ButtonPanel);
|
||||||
|
_sizeChangerComboBox = e.NameScope.Find<ComboBox>(PART_SizeChangerComboBox);
|
||||||
if (_previousButton != null) _previousButton.Click += OnButtonClick;
|
if (_previousButton != null) _previousButton.Click += OnButtonClick;
|
||||||
if (_nextButton != null) _nextButton.Click += OnButtonClick;
|
if (_nextButton != null) _nextButton.Click += OnButtonClick;
|
||||||
|
UpdateButtons();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<int> CurrentPageProperty = AvaloniaProperty.Register<Pagination, int>(
|
public static readonly StyledProperty<int> CurrentPageProperty = AvaloniaProperty.Register<Pagination, int>(
|
||||||
@@ -37,10 +44,7 @@ public class Pagination: TemplatedControl
|
|||||||
public int CurrentPage
|
public int CurrentPage
|
||||||
{
|
{
|
||||||
get => GetValue(CurrentPageProperty);
|
get => GetValue(CurrentPageProperty);
|
||||||
set {
|
set => SetValue(CurrentPageProperty, value);
|
||||||
int actualValue = CoercePage(value);
|
|
||||||
SetValue(CurrentPageProperty, actualValue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<int> TotalCountProperty = AvaloniaProperty.Register<Pagination, int>(
|
public static readonly StyledProperty<int> TotalCountProperty = AvaloniaProperty.Register<Pagination, int>(
|
||||||
@@ -54,9 +58,9 @@ public class Pagination: TemplatedControl
|
|||||||
get => GetValue(TotalCountProperty);
|
get => GetValue(TotalCountProperty);
|
||||||
set => SetValue(TotalCountProperty, value);
|
set => SetValue(TotalCountProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<int> PageSizeProperty = AvaloniaProperty.Register<Pagination, int>(
|
public static readonly StyledProperty<int> PageSizeProperty = AvaloniaProperty.Register<Pagination, int>(
|
||||||
nameof(PageSize));
|
nameof(PageSize), defaultValue: 100);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Page size.
|
/// Page size.
|
||||||
@@ -81,26 +85,13 @@ public class Pagination: TemplatedControl
|
|||||||
private set => SetAndRaise(PageCountProperty, ref _pageCount, value);
|
private set => SetAndRaise(PageCountProperty, ref _pageCount, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _startIndex;
|
public static readonly StyledProperty<AvaloniaList<int>> PageSizeOptionsProperty = AvaloniaProperty.Register<Pagination, AvaloniaList<int>>(
|
||||||
|
nameof(PageSizeOptions));
|
||||||
|
|
||||||
public static readonly DirectProperty<Pagination, int> StartIndexProperty = AvaloniaProperty.RegisterDirect<Pagination, int>(
|
public AvaloniaList<int> PageSizeOptions
|
||||||
nameof(StartIndex), o => o.StartIndex);
|
|
||||||
|
|
||||||
public int StartIndex
|
|
||||||
{
|
{
|
||||||
get => _startIndex;
|
get => GetValue(PageSizeOptionsProperty);
|
||||||
private set => SetAndRaise(StartIndexProperty, ref _startIndex, value);
|
set => SetValue(PageSizeOptionsProperty, value);
|
||||||
}
|
|
||||||
|
|
||||||
private int _endIndex;
|
|
||||||
|
|
||||||
public static readonly DirectProperty<Pagination, int> EndIndexProperty = AvaloniaProperty.RegisterDirect<Pagination, int>(
|
|
||||||
nameof(EndIndex), o => o.EndIndex);
|
|
||||||
|
|
||||||
public int EndIndex
|
|
||||||
{
|
|
||||||
get => _endIndex;
|
|
||||||
private set => SetAndRaise(EndIndexProperty, ref _endIndex, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<ControlTheme> PageButtonThemeProperty = AvaloniaProperty.Register<Pagination, ControlTheme>(
|
public static readonly StyledProperty<ControlTheme> PageButtonThemeProperty = AvaloniaProperty.Register<Pagination, ControlTheme>(
|
||||||
@@ -120,7 +111,16 @@ public class Pagination: TemplatedControl
|
|||||||
get => GetValue(ExpandButtonThemeProperty);
|
get => GetValue(ExpandButtonThemeProperty);
|
||||||
set => SetValue(ExpandButtonThemeProperty, value);
|
set => SetValue(ExpandButtonThemeProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||||
|
{
|
||||||
|
base.OnPropertyChanged(change);
|
||||||
|
if (change.Property == PageSizeProperty || change.Property == TotalCountProperty)
|
||||||
|
{
|
||||||
|
UpdateButtons();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OnButtonClick(object? sender, RoutedEventArgs e)
|
private void OnButtonClick(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (Equals(sender, _previousButton))
|
if (Equals(sender, _previousButton))
|
||||||
@@ -132,12 +132,22 @@ public class Pagination: TemplatedControl
|
|||||||
CurrentPage++;
|
CurrentPage++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int CoercePage(int page)
|
|
||||||
{
|
|
||||||
if (page < 1) return 1;
|
|
||||||
if (page > PageCount) return PageCount;
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private void UpdateButtons()
|
||||||
|
{
|
||||||
|
if (PageSize == 0) return;
|
||||||
|
int currentPage = CurrentPage;
|
||||||
|
|
||||||
|
int pageCount = TotalCount / PageSize;
|
||||||
|
int residue = TotalCount % PageSize;
|
||||||
|
if (residue > 0)
|
||||||
|
{
|
||||||
|
pageCount++;
|
||||||
|
}
|
||||||
|
_buttonPanel?.Children.Clear();
|
||||||
|
for (int i = 0; i < pageCount; i++)
|
||||||
|
{
|
||||||
|
_buttonPanel?.Children.Add(new Button { Content = i + 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user