Skip to main content

PipsPager

PipsPager is a page indicator control that displays a row of interactive dots (pips) representing pages in a paginated collection. Users click a pip or use the optional Previous/Next navigation buttons to change the selected page. When the number of pages exceeds MaxVisiblePips, the pips scroll automatically to keep the selected pip visible.

PipsPager is commonly used alongside a Carousel or CarouselPage, bound through SelectedPageIndex.

Useful Properties

You will probably use these properties most often:

PropertyTypeDefaultDescription
NumberOfPagesint0Total number of pages represented by the pips.
SelectedPageIndexint0Zero-based index of the currently selected page. Supports two-way binding. Clamped to [0, NumberOfPages - 1].
MaxVisiblePipsint5Maximum number of pips visible at once. When NumberOfPages exceeds this value, the pips scroll automatically. Minimum value is 1.
OrientationOrientationHorizontalLayout direction of the pips. Horizontal or Vertical.
IsPreviousButtonVisiblebooltrueShows or hides the Previous navigation button.
IsNextButtonVisiblebooltrueShows or hides the Next navigation button.
PreviousButtonThemeControlTheme?nullCustom theme applied to the Previous navigation button.
NextButtonThemeControlTheme?nullCustom theme applied to the Next navigation button.

Pseudo-classes

Pseudo-classCondition
:first-pageSelectedPageIndex is 0.
:last-pageSelectedPageIndex is NumberOfPages - 1 and NumberOfPages > 0.
:horizontalOrientation is Horizontal.
:verticalOrientation is Vertical.

Events

EventArgs typeDescription
SelectedIndexChangedPipsPagerSelectedIndexChangedEventArgsRaised when the selected page changes. Provides OldIndex and NewIndex.

Keyboard Navigation

  • Left / Up arrow: moves to the previous page.
  • Right / Down arrow: moves to the next page.
  • Home: jumps to the first page (index 0).
  • End: jumps to the last page (NumberOfPages - 1).

Styling Resource Keys

Override these resource keys on the PipsPager or an ancestor to customize pip indicator colors:

Resource keyDescription
PipsPagerSelectionIndicatorForegroundDefault pip color.
PipsPagerSelectionIndicatorForegroundSelectedSelected pip color.
PipsPagerSelectionIndicatorForegroundPointerOverPip color on pointer hover.
PipsPagerSelectionIndicatorForegroundPressedPip color when pressed.

Examples

Basic PipsPager

<PipsPager NumberOfPages="5" />

PipsPager in Code

var pager = new PipsPager
{
NumberOfPages = 5,
MaxVisiblePips = 5
};

Vertical Orientation

<PipsPager NumberOfPages="5" Orientation="Vertical" />

Without Navigation Buttons

<PipsPager NumberOfPages="10"
MaxVisiblePips="5"
IsPreviousButtonVisible="False"
IsNextButtonVisible="False" />

Bind SelectedPageIndex to a Carousel.SelectedIndex for synchronized navigation:

<Grid RowDefinitions="*,Auto">
<Carousel Name="GalleryCarousel"
SelectedIndex="{Binding #GalleryPager.SelectedPageIndex, Mode=TwoWay}">
<Carousel.Items>
<Border Background="#E3F2FD" CornerRadius="8">
<TextBlock Text="Page 1" FontSize="30"
VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<Border Background="#C8E6C9" CornerRadius="8">
<TextBlock Text="Page 2" FontSize="30"
VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<Border Background="#FFE0B2" CornerRadius="8">
<TextBlock Text="Page 3" FontSize="30"
VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
</Carousel.Items>
</Carousel>

<PipsPager Name="GalleryPager"
Grid.Row="1"
NumberOfPages="3"
HorizontalAlignment="Center"
Margin="0,12,0,0" />
</Grid>

Two-Way Binding with a CarouselPage

<Grid RowDefinitions="*,Auto">
<CarouselPage Name="DemoCarousel"
SelectedIndex="{Binding #Pager.SelectedPageIndex, Mode=TwoWay}">
<ContentPage Header="Welcome">
<TextBlock Text="Welcome" FontSize="28"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</ContentPage>
<ContentPage Header="Features">
<TextBlock Text="Features" FontSize="28"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</ContentPage>
<ContentPage Header="Get Started">
<TextBlock Text="Get Started" FontSize="28"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</ContentPage>
</CarouselPage>

<PipsPager Name="Pager"
Grid.Row="1"
NumberOfPages="3"
HorizontalAlignment="Center"
Margin="0,12,0,0" />
</Grid>

Large Collections with Auto-Scrolling Pips

When NumberOfPages exceeds MaxVisiblePips, the pip strip scrolls automatically to keep the selected pip visible:

<PipsPager NumberOfPages="50"
MaxVisiblePips="7"
SelectedPageIndex="25" />

Responding to Selection Changes

pager.SelectedIndexChanged += (sender, e) =>
{
Console.WriteLine($"Changed from page {e.OldIndex} to {e.NewIndex}");
};

Custom Pip Colors

Override the indicator resource keys on the PipsPager to change pip colors:

<PipsPager NumberOfPages="5" MaxVisiblePips="5">
<PipsPager.Resources>
<SolidColorBrush x:Key="PipsPagerSelectionIndicatorForeground" Color="Orange" />
<SolidColorBrush x:Key="PipsPagerSelectionIndicatorForegroundSelected" Color="Blue" />
<SolidColorBrush x:Key="PipsPagerSelectionIndicatorForegroundPointerOver" Color="Gold" />
</PipsPager.Resources>
</PipsPager>

Custom Button Themes

Replace the default chevron buttons with custom themed buttons using PreviousButtonTheme and NextButtonTheme:

<PipsPager NumberOfPages="5" MaxVisiblePips="5">
<PipsPager.Resources>
<ControlTheme x:Key="PrevTheme" TargetType="Button">
<Setter Property="Content" Value="Prev" />
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Padding" Value="8,2" />
<Setter Property="Margin" Value="0,0,8,0" />
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}" CornerRadius="4">
<ContentPresenter Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}" />
</Border>
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme x:Key="NextTheme" TargetType="Button">
<Setter Property="Content" Value="Next" />
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Padding" Value="8,2" />
<Setter Property="Margin" Value="8,0,0,0" />
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}" CornerRadius="4">
<ContentPresenter Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}" />
</Border>
</ControlTemplate>
</Setter>
</ControlTheme>
</PipsPager.Resources>
<PipsPager.PreviousButtonTheme>
<StaticResource ResourceKey="PrevTheme" />
</PipsPager.PreviousButtonTheme>
<PipsPager.NextButtonTheme>
<StaticResource ResourceKey="NextTheme" />
</PipsPager.NextButtonTheme>
</PipsPager>

Custom Pip Templates (Pill-Shaped Indicator)

Use Style selectors targeting the inner ListBoxItem to replace the default dot shape. This example transforms the selected pip from a circle into a horizontal pill:

<PipsPager NumberOfPages="5"
IsPreviousButtonVisible="False"
IsNextButtonVisible="False">
<PipsPager.Styles>
<Style Selector="PipsPager /template/ ListBox ListBoxItem">
<Setter Property="Width" Value="24" />
<Setter Property="Height" Value="24" />
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="2,0" />
<Setter Property="MinWidth" Value="0" />
<Setter Property="MinHeight" Value="0" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template">
<ControlTemplate>
<Grid Background="Transparent">
<Border Name="Pip"
Width="8" Height="8" CornerRadius="4"
HorizontalAlignment="Center" VerticalAlignment="Center"
Background="#C0C0C0">
<Border.Transitions>
<Transitions>
<DoubleTransition Property="Width" Duration="0:0:0.2" Easing="CubicEaseOut" />
<DoubleTransition Property="Height" Duration="0:0:0.2" Easing="CubicEaseOut" />
<CornerRadiusTransition Property="CornerRadius" Duration="0:0:0.2" Easing="CubicEaseOut" />
<BrushTransition Property="Background" Duration="0:0:0.2" />
</Transitions>
</Border.Transitions>
</Border>
</Grid>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="PipsPager /template/ ListBox ListBoxItem:pointerover /template/ Border#Pip">
<Setter Property="Width" Value="10" />
<Setter Property="Height" Value="10" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="Background" Value="#909090" />
</Style>
<Style Selector="PipsPager /template/ ListBox ListBoxItem:selected /template/ Border#Pip">
<Setter Property="Width" Value="24" />
<Setter Property="Height" Value="8" />
<Setter Property="CornerRadius" Value="4" />
<Setter Property="Background" Value="#FF6B35" />
</Style>
<Style Selector="PipsPager /template/ ListBox ListBoxItem:selected:pointerover /template/ Border#Pip">
<Setter Property="Width" Value="24" />
<Setter Property="Height" Value="8" />
<Setter Property="CornerRadius" Value="4" />
<Setter Property="Background" Value="#E85A2A" />
</Style>
</PipsPager.Styles>
</PipsPager>

Programmatic Control

// Set page count
pager.NumberOfPages = 20;

// Jump to a specific page
pager.SelectedPageIndex = 10;

// Limit visible pips
pager.MaxVisiblePips = 7;

// Switch to vertical
pager.Orientation = Orientation.Vertical;

// Hide navigation buttons
pager.IsPreviousButtonVisible = false;
pager.IsNextButtonVisible = false;

See also