feat: improve popup behavior.

This commit is contained in:
rabbitism
2023-05-07 22:23:12 +08:00
parent 642fcb3aeb
commit e0dfd64681
5 changed files with 109 additions and 10 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 });
} }
} }
} }

View 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; }
}

View File

@@ -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);
}
} }