Feature Proposal: PagerControl
See original GitHub issueThe WinUI Team has opened a Spec for this feature.
Proposal: New UI Pagination Widget
Summary
This widget would provide a customizable pager UI, generic states, and generic events that can be configured to navigate pages for several view controls.
Rationale
- Desired by community - tied with Make Grid Better for most engaged with issue on our repo.
- Desired by 8/12 MVPs in survey.
- Several UI teams actively interested in parallel development.
The absence of a standard UI pager control, last seen as DataPager in Silverlight, has been a pain point in both WPF and UWP that has forced a variety of unfavorable workarounds for developers. Inclusion of this control in UWP would resolve an ecosystem gap and enable developers to efficiently deliver UI paging experiences in their applications. Through XAML Islands, it may also provide an opportunity to benefit WPF developers working with DataGrid or ListView. The scope of this proposal is not provide a data paging solution at this time but to start with UI paging as a foundation on top of which data paging may be later integrated.
Requirements
# | Feature | Priority |
---|---|---|
1 | Can support the option to have multiple display modes as the core navigation component (NumberBox, ComboBox, Button panel). | Must |
2 | Can have optional text and/or glyphic bookend navigation controls (First/Last, Next/Back, none). | Must |
2 | Can be used to page GridView, ListView, DataGrid, and ItemsRepeater. | Must |
4 | Support for non-data binding/indeterminate page count solutions. | Must |
5 | Designed to support later possible integrated data paging component. | Must |
Important Notes
Here are how the three configurations could look:
ComboBox configuration
NumberBox configuration:
Button panel configuration:
Usage Examples
Using a button panel as the display mode.
<UserControl x:Class="DataPagerSample.MainPage">
<Grid x:Name="LayoutRoot" RowDefinitions="*,Auto">
<GridView x:Name="gridView1" ... />
<muxc:UIPager x:Name="uiPager1"
Source="{Binding}"
LastButton="AlwaysVisible"
FirstButton="AlwaysVisible"
NumberOfIndicesShowing="7"
EllipsisMaxBefore="5"
EllipsisMaxAfter="1"
EllipsisShowBounds="True" />
</Grid>
</UserControl>
Using an editable ComboBox as the display mode.
<UserControl x:Class="DataPagerSample.MainPage">
<Grid x:Name="LayoutRoot" RowDefinitions="*,Auto">
<GridView x:Name="gridView1" ... />
<muxc:UIPager x:Name="uiPager1"
Source="{Binding}"
DisplayMode="EditableComboBox"
NextButtonText="Prev"
PreviousButtonText="Next"
PrefixText="Page"
TotalNumberOfPages="10" />
</Grid>
</UserControl>
Visual Components
Component | Notes |
---|---|
DisplayMode | * Used to set either a button panel (default) or an editable ComboBox as the indexing component. * When set to be a button panel, the number of visible indices can be specified. ![]() ![]() |
LastButton | * Button displaying text and/or glyph indicating that the user may navigate to the last index. * Automatically disabled when at last index. * Can be set to not be visible when at the last index. ![]() |
FirstButton | * Button displaying text and/or glyph indicating that the user may navigate to the first index. * Automatically disabled when at first index. * Can be set to not be visible when at the first index. ![]() |
NextButton | * Button displaying text and/or glyph indicating that the user may navigate to the next index. * Automatically disabled when at last index. * Can be set to not be visible when at the last index. ![]() |
PreviousButton | * Button displaying text and/or glyph indicating that the user may navigate to the previous index. * Automatically disabled when at first index. * Can be set to not be visible when at the first index. ![]() |
Ellipsis | * Button, often reading “…”, used between indexes and before or after the first/last index to indicate an accessible but omitted range of indexes. * MaxBefore and MaxAfter properties can be used to set how many indices appear between the current page and the ellipsis before/after it. * Visibility of the first/last index can be disabled. * Only visible when using button panel as the display mode. ![]() |
PrefixText | * Text displayed before the editable ComboBox indexing component. ![]() |
NumberOfPages | * When a total number of indices (N) is given, this suffix string will appear after the editable ComboBox indexing component and read “of N”. Localization will put “N” where it should be in a given language. ![]() |
Accessibility
State | Action | Narrator |
---|---|---|
UI pager is first focused on by tabbing | Focus defaults to the next page button if available (current page otherwise) after announcing accessible name of UI pager. | “Page selector. Next page is N." |
UI pager is tabbed through | Tab Button: Will go through all actionable items in order without regard to groups. Arrow keys: Will be able to explore groups in the specified directions. Pressing the down arrow key at the bottom of the ComboBox will wrap the user to the top. Escape: Will escape UI pager. Enter and Spacebar: Will select the component focused on. Home: Will move focus to “go back” elements. In the ComboBox, it will jump the user to the first index. End: Will move focus to “go forward” elements. In the ComboBox, it will jump the user to the last index. |
Narrator will announce an accessible name of the visual component. Ex: “first page button” “previous page button” “1st page” “current page” "page selection drop down menu: current page is 1” |
API Surface Example
<PagerControl
DisplayMode = { Auto | ComboBox | NumberBox | ButtonPanel }
NumberOfIndicesShowing = { int }
LastButton = { Auto | AlwaysVisible | HiddenOnLast | None }
LastButtonGlyph = { string }
LastButtonText = { string }
LastButtonStyle = { string }
FirstButton = { Auto | AlwaysVisible | HiddenOnFirst | None }
FirstButtonGlyph = { string }
FirstButtonText = { string }
FirstButtonStyle = { string }
NextButton = { Auto | AlwaysVisible | HiddenOnLast | None }
NextButtonGlyph = { string }
NextButtonText = { string }
NextButtonStyle = { string }
PreviousButton = { Auto | AlwaysVisible | HiddenOnFirst | None }
PreviousButtonGlyph = { string }
PreviousButtonText = { string }
PreviousButtonStyle = { string }
EllipsisEnabled = { True | False }
EllipsisMaxBefore = { int }
EllipsisMaxAfter = { int }
EllipsisShowBounds = { True | False }
PrefixText = { string }
NumberOfPages = { int } >
</PagerControl>
Related
Issue Analytics
- State:
- Created 5 years ago
- Reactions:14
- Comments:56 (49 by maintainers)
Are there plans to also provide this control in WinUI 3?
The DisplayMode property could be used to enable a simple step based representation, as used by Windows and XBox OOBE sequences - and could be useful for onboarding scenarios for app developers.
You could even allow it to be template-able, but as a default appearance, something like this would fit with UWP patterns.
There could be properties to hide or show the labels, or it could be part of the template.