feat: improve popup behavior.
This commit is contained in:
@@ -13,6 +13,10 @@
|
|||||||
<viewModels:PaginationDemoViewModel />
|
<viewModels:PaginationDemoViewModel />
|
||||||
</Design.DataContext>
|
</Design.DataContext>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<u:Pagination PageSizeOptions="{Binding PageSizes}" TotalCount="300" />
|
<TextBlock Text="{Binding #page.CurrentPage}" />
|
||||||
|
<u:Pagination
|
||||||
|
Name="page"
|
||||||
|
PageSizeOptions="{Binding PageSizes}"
|
||||||
|
TotalCount="300" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -24,12 +24,33 @@
|
|||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate TargetType="u:PaginationExpandButton">
|
<ControlTemplate TargetType="u:PaginationExpandButton">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Button Name="button" Content="..." />
|
<Button Name="PART_Button" Content="..." />
|
||||||
<Popup
|
<Popup
|
||||||
|
Name="{x:Static u:PaginationExpandButton.PART_Popup}"
|
||||||
IsLightDismissEnabled="True"
|
IsLightDismissEnabled="True"
|
||||||
IsOpen="{Binding #button.IsPointerOver}"
|
IsOpen="{TemplateBinding IsDropdownOpen,
|
||||||
PlacementTarget="button">
|
Mode=TwoWay}"
|
||||||
<ListBox Background="White" ItemsSource="{TemplateBinding Pages}" />
|
PlacementTarget="PART_Button">
|
||||||
|
<Border
|
||||||
|
Margin="4,0,4,4"
|
||||||
|
Padding="4"
|
||||||
|
Background="White"
|
||||||
|
BorderBrush="LightGray"
|
||||||
|
BorderThickness="1"
|
||||||
|
BoxShadow="0 0 8 0 #1A000000"
|
||||||
|
ClipToBounds="True"
|
||||||
|
CornerRadius="6">
|
||||||
|
<ListBox
|
||||||
|
MinWidth="50"
|
||||||
|
MaxHeight="300"
|
||||||
|
ItemsSource="{TemplateBinding Pages}">
|
||||||
|
<ListBox.ItemContainerTheme>
|
||||||
|
<ControlTheme BasedOn="{StaticResource {x:Type ListBoxItem}}" TargetType="ListBoxItem">
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||||
|
</ControlTheme>
|
||||||
|
</ListBox.ItemContainerTheme>
|
||||||
|
</ListBox>
|
||||||
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class Pagination: TemplatedControl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<int> PageSizeProperty = AvaloniaProperty.Register<Pagination, int>(
|
public static readonly StyledProperty<int> PageSizeProperty = AvaloniaProperty.Register<Pagination, int>(
|
||||||
nameof(PageSize), defaultValue: 50);
|
nameof(PageSize), defaultValue: 10);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Page size.
|
/// Page size.
|
||||||
@@ -144,7 +144,7 @@ public class Pagination: TemplatedControl
|
|||||||
private void UpdateButtons()
|
private void UpdateButtons()
|
||||||
{
|
{
|
||||||
if (PageSize == 0) return;
|
if (PageSize == 0) return;
|
||||||
int currentPage = CurrentPage;
|
int currentIndex = CurrentPage * PageSize;
|
||||||
|
|
||||||
int pageCount = TotalCount / PageSize;
|
int pageCount = TotalCount / PageSize;
|
||||||
int residue = TotalCount % PageSize;
|
int residue = TotalCount % PageSize;
|
||||||
@@ -162,7 +162,7 @@ public class Pagination: TemplatedControl
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_buttonPanel?.Children.Add(new Button { Content = i + 1 });
|
_buttonPanel?.Children.Add(new PaginationButton { Content = i + 1, Page = i + 1 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/Ursa/Controls/Pagination/PaginationButton.cs
Normal file
14
src/Ursa/Controls/Pagination/PaginationButton.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Styling;
|
||||||
|
|
||||||
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
|
public class PaginationButton: Button, IStyleable
|
||||||
|
{
|
||||||
|
Type IStyleable.StyleKey => typeof(Button);
|
||||||
|
|
||||||
|
public int Page { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,11 +1,21 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Metadata;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Input;
|
||||||
|
|
||||||
namespace Ursa.Controls;
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
|
[TemplatePart(PART_Button, typeof(Button))]
|
||||||
|
[TemplatePart(PART_Popup, typeof(Popup))]
|
||||||
public class PaginationExpandButton: TemplatedControl
|
public class PaginationExpandButton: TemplatedControl
|
||||||
{
|
{
|
||||||
|
public const string PART_Button = "PART_Button";
|
||||||
|
public const string PART_Popup = "PART_Popup";
|
||||||
|
private Popup? _popup;
|
||||||
|
private Button? _button;
|
||||||
|
|
||||||
public static readonly StyledProperty<AvaloniaList<int>> PagesProperty = AvaloniaProperty.Register<PaginationExpandButton, AvaloniaList<int>>(
|
public static readonly StyledProperty<AvaloniaList<int>> PagesProperty = AvaloniaProperty.Register<PaginationExpandButton, AvaloniaList<int>>(
|
||||||
nameof(Pages));
|
nameof(Pages));
|
||||||
|
|
||||||
@@ -14,6 +24,56 @@ public class PaginationExpandButton: TemplatedControl
|
|||||||
get => GetValue(PagesProperty);
|
get => GetValue(PagesProperty);
|
||||||
set => SetValue(PagesProperty, value);
|
set => SetValue(PagesProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<bool> IsDropdownOpenProperty = AvaloniaProperty.Register<PaginationExpandButton, bool>(
|
||||||
|
nameof(IsDropdownOpen));
|
||||||
|
|
||||||
|
public bool IsDropdownOpen
|
||||||
|
{
|
||||||
|
get => GetValue(IsDropdownOpenProperty);
|
||||||
|
set => SetValue(IsDropdownOpenProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnApplyTemplate(e);
|
||||||
|
_popup = e.NameScope.Find<Popup>(PART_Popup);
|
||||||
|
_button = e.NameScope.Find<Button>(PART_Button);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPointerEntered(PointerEventArgs e)
|
||||||
|
{
|
||||||
|
if (!e.Handled && e.Source is Visual source )
|
||||||
|
{
|
||||||
|
SetCurrentValue(IsDropdownOpenProperty, true);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
base.OnPointerEntered(e);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPointerExited(PointerEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnPointerExited(e);
|
||||||
|
// IsDropdownOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!e.Handled && e.Source is Visual source)
|
||||||
|
{
|
||||||
|
if (_popup?.IsInsidePopup(source) == true)
|
||||||
|
{
|
||||||
|
SetCurrentValue(IsDropdownOpenProperty, false);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//SetCurrentValue(IsDropdownOpenProperty, !IsDropdownOpen);
|
||||||
|
SetCurrentValue(IsDropdownOpenProperty, false);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.OnPointerReleased(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user