Pr3/carousel page (#772)

* feat: add CarouselPage and PipsPager.

* feat: add PipsPager control and integrate into index

* feat: add PipsPagerDemo and integrate into MainView

---------

Co-authored-by: Zhang Dian <54255897+zdpcdt@users.noreply.github.com>
This commit is contained in:
Dong Bin
2026-03-21 17:58:35 +08:00
committed by GitHub
parent 96f7f3d1e1
commit b3b7459088
15 changed files with 400 additions and 3 deletions

View File

@@ -0,0 +1,69 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Semi.Avalonia.Demo.Pages.CarouselPageDemo">
<DockPanel>
<ScrollViewer DockPanel.Dock="Right" Width="220">
<StackPanel Margin="12" Spacing="8">
<TextBlock Text="Configuration" FontWeight="SemiBold" FontSize="16"
Foreground="{DynamicResource SystemControlHighlightAccentBrush}" />
<TextBlock Text="Navigation" FontWeight="SemiBold" FontSize="13" />
<StackPanel Spacing="6">
<Button Content="Previous" Click="OnPrevious" HorizontalAlignment="Stretch" />
<Button Content="Next" Click="OnNext" HorizontalAlignment="Stretch" />
</StackPanel>
<Separator />
<TextBlock Text="Status" FontWeight="SemiBold" FontSize="13" />
<TextBlock Name="StatusText" Text="Page 1 of 3" Opacity="0.7" TextWrapping="Wrap" />
</StackPanel>
</ScrollViewer>
<Border DockPanel.Dock="Right" Width="1"
Background="{DynamicResource SystemControlForegroundBaseMediumLowBrush}" />
<Border Margin="12"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="1" CornerRadius="6" ClipToBounds="True">
<Panel>
<CarouselPage Name="DemoCarousel"
SelectionChanged="OnSelectionChanged">
<ContentPage Header="Welcome">
<StackPanel Margin="24" Spacing="12"
HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="Welcome" FontSize="28" FontWeight="Bold"
HorizontalAlignment="Center" />
<TextBlock Text="Swipe left or use the buttons to navigate."
TextWrapping="Wrap" Opacity="0.7" TextAlignment="Center" MaxWidth="280" />
</StackPanel>
</ContentPage>
<ContentPage Header="Explore">
<StackPanel Margin="24" Spacing="12"
HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="Explore" FontSize="28" FontWeight="Bold"
HorizontalAlignment="Center" />
<TextBlock Text="CarouselPage supports scroll-based and transition-based navigation modes."
TextWrapping="Wrap" Opacity="0.7" TextAlignment="Center" MaxWidth="280" />
</StackPanel>
</ContentPage>
<ContentPage Header="Get Started">
<StackPanel Margin="24" Spacing="12"
HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="Get Started" FontSize="28" FontWeight="Bold"
HorizontalAlignment="Center" />
<TextBlock Text="Use SelectedIndex to jump to any page, or assign a PageTransition for animated switching."
TextWrapping="Wrap" Opacity="0.7" TextAlignment="Center" MaxWidth="280" />
</StackPanel>
</ContentPage>
</CarouselPage>
<PipsPager HorizontalAlignment="Center"
VerticalAlignment="Bottom" Margin="0,0,0,20"
NumberOfPages="3"
SelectedPageIndex="{Binding #DemoCarousel.SelectedIndex}" />
</Panel>
</Border>
</DockPanel>
</UserControl>

View File

@@ -0,0 +1,34 @@
using System.Collections;
using Avalonia.Controls;
using Avalonia.Interactivity;
namespace Semi.Avalonia.Demo.Pages;
public partial class CarouselPageDemo : UserControl
{
public CarouselPageDemo()
{
InitializeComponent();
}
private void OnPrevious(object? sender, RoutedEventArgs e)
{
if (DemoCarousel.SelectedIndex > 0)
DemoCarousel.SelectedIndex--;
}
private void OnNext(object? sender, RoutedEventArgs e)
{
var pageCount = (DemoCarousel.Pages as IList)?.Count ?? 0;
if (DemoCarousel.SelectedIndex < pageCount - 1)
DemoCarousel.SelectedIndex++;
}
private void OnSelectionChanged(object? sender, PageSelectionChangedEventArgs e)
{
if (StatusText == null)
return;
var pageCount = (DemoCarousel.Pages as IList)?.Count ?? 0;
StatusText.Text = $"Page {DemoCarousel.SelectedIndex + 1} of {pageCount}";
}
}

View File

@@ -0,0 +1,99 @@
<UserControl
x:Class="Semi.Avalonia.Demo.Pages.PipsPagerDemo"
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"
d:DesignHeight="600"
d:DesignWidth="800"
mc:Ignorable="d">
<ScrollViewer>
<StackPanel HorizontalAlignment="Left" Spacing="16" Margin="0,0,0,20">
<!-- Horizontal PipsPager -->
<TextBlock Classes="H6" Text="Horizontal" />
<PipsPager
NumberOfPages="8"
Orientation="Horizontal" />
<!-- Vertical PipsPager -->
<TextBlock Classes="H6" Text="Vertical" />
<PipsPager
NumberOfPages="8"
Orientation="Vertical" />
<!-- Linked with Carousel -->
<TextBlock Classes="H6" Text="Linked with Carousel" />
<Panel>
<Carousel
Name="DemoCarousel"
Height="160">
<Border Background="#EAF5FF">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#1C1F23"
Text="Page 1" />
</Border>
<Border Background="#F9F9F9">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#1C1F23"
Text="Page 2" />
</Border>
<Border Background="#FFF8EA">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#1C1F23"
Text="Page 3" />
</Border>
<Border Background="#FEF2ED">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#1C1F23"
Text="Page 4" />
</Border>
<Border Background="#F0F5FF">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#1C1F23"
Text="Page 5" />
</Border>
</Carousel>
<ThemeVariantScope RequestedThemeVariant="Light">
<PipsPager
Name="LinkedPager"
NumberOfPages="5"
Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Margin="0,0,0,8"
SelectedPageIndex="{Binding #DemoCarousel.SelectedIndex}" />
</ThemeVariantScope>
</Panel>
<!-- Various page counts -->
<TextBlock Classes="H6" Text="Various Page Counts" />
<StackPanel Spacing="12">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock VerticalAlignment="Center" Width="80" Text="3 pages" />
<PipsPager NumberOfPages="3" Orientation="Horizontal" />
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock VerticalAlignment="Center" Width="80" Text="5 pages" />
<PipsPager NumberOfPages="5" Orientation="Horizontal" />
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock VerticalAlignment="Center" Width="80" Text="10 pages" />
<PipsPager NumberOfPages="10" Orientation="Horizontal" />
</StackPanel>
</StackPanel>
</StackPanel>
</ScrollViewer>
</UserControl>

View File

@@ -0,0 +1,12 @@
using Avalonia.Controls;
namespace Semi.Avalonia.Demo.Pages;
public partial class PipsPagerDemo : UserControl
{
public PipsPagerDemo()
{
InitializeComponent();
}
}

View File

@@ -200,6 +200,9 @@
<TabItem Header="ContentPage">
<pages:ContentPageDemo />
</TabItem>
<TabItem Header="CarouselPage">
<pages:CarouselPageDemo />
</TabItem>
<TabItem Header="DrawerPage">
<pages:DrawerPageDemo />
</TabItem>
@@ -222,6 +225,9 @@
<TabItem Header="Carousel">
<pages:CarouselDemo />
</TabItem>
<TabItem Header="PipsPager">
<pages:PipsPagerDemo />
</TabItem>
<TabItem Header="Expander">
<pages:ExpanderDemo />
</TabItem>