WPF 之列表分页控件
框架使用大于等于.NET40
。
Visual Studio 2022
。
项目使用 MIT 开源许可协议。
新建Pagination
自定义控件继承自Control
。
正常模式分页 在外部套Grid
分为0 - 5
列:
Grid.Column 0
总页数共多少300
条。Grid.Column 1
输入每页显示多少10
条。Grid.Column 2 上一页
按钮。Grid.Column 3 所有页码
按钮此处使用ListBox
。Grid.Column 4 下一页
按钮。Grid.Column 5
跳转页1
码输入框。
精简模式分页 在外部套Grid
分为0 - 9
列:
Grid.Column 0
总页数共多少300
条。Grid.Column 2
输入每页显示多少10
条。Grid.Column 3 条 / 页
。Grid.Column 5 上一页
按钮。Grid.Column 7
跳转页1
码输入框。Grid.Column 9 下一页
按钮。
每页显示与跳转页码数控制只允许输入数字,不允许粘贴。
实现代码
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="10"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="10"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="5"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="5"/> | |
<ColumnDefinition Width="Auto"/> |
1) Pagination.cs 如下:
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Input; | |
using WPFDevelopers.Helpers; | |
namespace WPFDevelopers.Controls | |
{ | |
[ | ]|
[ | ]|
[ | ]|
public class Pagination : Control | |
{ | |
private const string CountPerPageTextBoxTemplateName = "PART_CountPerPageTextBox"; | |
private const string JustPageTextBoxTemplateName = "PART_JumpPageTextBox"; | |
private const string ListBoxTemplateName = "PART_ListBox"; | |
private const string Ellipsis = "···"; | |
private static readonly Type _typeofSelf = typeof(Pagination); | |
private TextBox _countPerPageTextBox; | |
private TextBox _jumpPageTextBox; | |
private ListBox _listBox; | |
static Pagination() | |
{ | |
InitializeCommands(); | |
DefaultStyleKeyProperty.OverrideMetadata(_typeofSelf, new FrameworkPropertyMetadata(_typeofSelf)); | |
} | |
public override void OnApplyTemplate() | |
{ | |
base.OnApplyTemplate(); | |
UnsubscribeEvents(); | |
_countPerPageTextBox = GetTemplateChild(CountPerPageTextBoxTemplateName) as TextBox; | |
if (_countPerPageTextBox != null) | |
{ | |
_countPerPageTextBox.ContextMenu = null; | |
_countPerPageTextBox.PreviewTextInput += _countPerPageTextBox_PreviewTextInput; | |
_countPerPageTextBox.PreviewKeyDown += _countPerPageTextBox_PreviewKeyDown; | |
} | |
_jumpPageTextBox = GetTemplateChild(JustPageTextBoxTemplateName) as TextBox; | |
if (_jumpPageTextBox != null) | |
{ | |
_jumpPageTextBox.ContextMenu = null; | |
_jumpPageTextBox.PreviewTextInput += _countPerPageTextBox_PreviewTextInput; | |
_jumpPageTextBox.PreviewKeyDown += _countPerPageTextBox_PreviewKeyDown; | |
} | |
_listBox = GetTemplateChild(ListBoxTemplateName) as ListBox; | |
Init(); | |
SubscribeEvents(); | |
} | |
private void _countPerPageTextBox_PreviewKeyDown(object sender, KeyEventArgs e) | |
{ | |
if (Key.Space == e.Key | |
|| | |
Key.V == e.Key | |
&& e.KeyboardDevice.Modifiers == ModifierKeys.Control) | |
e.Handled = true; | |
} | |
private void _countPerPageTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) | |
{ | |
e.Handled = ControlsHelper.IsNumber(e.Text); | |
} | |
private static void InitializeCommands() | |
{ | |
PrevCommand = new RoutedCommand("Prev", _typeofSelf); | |
NextCommand = new RoutedCommand("Next", _typeofSelf); | |
CommandManager.RegisterClassCommandBinding(_typeofSelf, | |
new CommandBinding(PrevCommand, OnPrevCommand, OnCanPrevCommand)); | |
CommandManager.RegisterClassCommandBinding(_typeofSelf, | |
new CommandBinding(NextCommand, OnNextCommand, OnCanNextCommand)); | |
} | |
public static RoutedCommand PrevCommand { get; private set; } | |
public static RoutedCommand NextCommand { get; private set; } | |
private static void OnPrevCommand(object sender, RoutedEventArgs e) | |
{ | |
var ctrl = sender as Pagination; | |
ctrl.Current--; | |
} | |
private static void OnCanPrevCommand(object sender, CanExecuteRoutedEventArgs e) | |
{ | |
var ctrl = sender as Pagination; | |
e.CanExecute = ctrl.Current > 1; | |
} | |
private static void OnNextCommand(object sender, RoutedEventArgs e) | |
{ | |
var ctrl = sender as Pagination; | |
ctrl.Current++; | |
} | |
private static void OnCanNextCommand(object sender, CanExecuteRoutedEventArgs e) | |
{ | |
var ctrl = sender as Pagination; | |
e.CanExecute = ctrl.Current < ctrl.PageCount; | |
} | |
private static readonly DependencyPropertyKey PagesPropertyKey = | |
DependencyProperty.RegisterReadOnly("Pages", typeof(IEnumerable<string>), _typeofSelf, | |
new PropertyMetadata(null)); | |
public static readonly DependencyProperty PagesProperty = PagesPropertyKey.DependencyProperty; | |
public IEnumerable<string> Pages => (IEnumerable<string>) GetValue(PagesProperty); | |
private static readonly DependencyPropertyKey PageCountPropertyKey = | |
DependencyProperty.RegisterReadOnly("PageCount", typeof(int), _typeofSelf, | |
new PropertyMetadata(1, OnPageCountPropertyChanged)); | |
public static readonly DependencyProperty PageCountProperty = PageCountPropertyKey.DependencyProperty; | |
public int PageCount => (int) GetValue(PageCountProperty); | |
private static void OnPageCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | |
{ | |
var ctrl = d as Pagination; | |
var pageCount = (int) e.NewValue; | |
/* | |
if (ctrl._jumpPageTextBox != null) | |
ctrl._jumpPageTextBox.Maximum = pageCount; | |
*/ | |
} | |
public static readonly DependencyProperty IsLiteProperty = | |
DependencyProperty.Register("IsLite", typeof(bool), _typeofSelf, new PropertyMetadata(false)); | |
public bool IsLite | |
{ | |
get => (bool) GetValue(IsLiteProperty); | |
set => SetValue(IsLiteProperty, value); | |
} | |
public static readonly DependencyProperty CountProperty = DependencyProperty.Register("Count", typeof(int), | |
_typeofSelf, new PropertyMetadata(0, OnCountPropertyChanged, CoerceCount)); | |
public int Count | |
{ | |
get => (int) GetValue(CountProperty); | |
set => SetValue(CountProperty, value); | |
} | |
private static object CoerceCount(DependencyObject d, object value) | |
{ | |
var count = (int) value; | |
return Math.Max(count, 0); | |
} | |
private static void OnCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | |
{ | |
var ctrl = d as Pagination; | |
var count = (int) e.NewValue; | |
ctrl.SetValue(PageCountPropertyKey, (int) Math.Ceiling(count * 1.0 / ctrl.CountPerPage)); | |
ctrl.UpdatePages(); | |
} | |
public static readonly DependencyProperty CountPerPageProperty = DependencyProperty.Register("CountPerPage", | |
typeof(int), _typeofSelf, new PropertyMetadata(50, OnCountPerPagePropertyChanged, CoerceCountPerPage)); | |
public int CountPerPage | |
{ | |
get => (int) GetValue(CountPerPageProperty); | |
set => SetValue(CountPerPageProperty, value); | |
} | |
private static object CoerceCountPerPage(DependencyObject d, object value) | |
{ | |
var countPerPage = (int) value; | |
return Math.Max(countPerPage, 1); | |
} | |
private static void OnCountPerPagePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | |
{ | |
var ctrl = d as Pagination; | |
var countPerPage = (int) e.NewValue; | |
if (ctrl._countPerPageTextBox != null) | |
ctrl._countPerPageTextBox.Text = countPerPage.ToString(); | |
ctrl.SetValue(PageCountPropertyKey, (int) Math.Ceiling(ctrl.Count * 1.0 / countPerPage)); | |
if (ctrl.Current != 1) | |
ctrl.Current = 1; | |
else | |
ctrl.UpdatePages(); | |
} | |
public static readonly DependencyProperty CurrentProperty = DependencyProperty.Register("Current", typeof(int), | |
_typeofSelf, new PropertyMetadata(1, OnCurrentPropertyChanged, CoerceCurrent)); | |
public int Current | |
{ | |
get => (int) GetValue(CurrentProperty); | |
set => SetValue(CurrentProperty, value); | |
} | |
private static object CoerceCurrent(DependencyObject d, object value) | |
{ | |
var current = (int) value; | |
var ctrl = d as Pagination; | |
return Math.Max(current, 1); | |
} | |
private static void OnCurrentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | |
{ | |
var ctrl = d as Pagination; | |
var current = (int) e.NewValue; | |
if (ctrl._listBox != null) | |
ctrl._listBox.SelectedItem = current.ToString(); | |
if (ctrl._jumpPageTextBox != null) | |
ctrl._jumpPageTextBox.Text = current.ToString(); | |
ctrl.UpdatePages(); | |
} | |
/// <summary> | |
/// 分页 | |
/// </summary> | |
private void OnCountPerPageTextBoxChanged(object sender, TextChangedEventArgs e) | |
{ | |
if (int.TryParse(_countPerPageTextBox.Text, out var _ountPerPage)) | |
CountPerPage = _ountPerPage; | |
} | |
/// <summary> | |
/// 跳转页 | |
/// </summary> | |
private void OnJumpPageTextBoxChanged(object sender, TextChangedEventArgs e) | |
{ | |
if (int.TryParse(_jumpPageTextBox.Text, out var _current)) | |
Current = _current; | |
} | |
/// <summary> | |
/// 选择页 | |
/// </summary> | |
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) | |
{ | |
if (_listBox.SelectedItem == null) | |
return; | |
Current = int.Parse(_listBox.SelectedItem.ToString()); | |
} | |
private void Init() | |
{ | |
SetValue(PageCountPropertyKey, (int) Math.Ceiling(Count * 1.0 / CountPerPage)); | |
_jumpPageTextBox.Text = Current.ToString(); | |
//_jumpPageTextBox.Maximum = PageCount; | |
_countPerPageTextBox.Text = CountPerPage.ToString(); | |
if (_listBox != null) | |
_listBox.SelectedItem = Current.ToString(); | |
} | |
private void UnsubscribeEvents() | |
{ | |
if (_countPerPageTextBox != null) | |
_countPerPageTextBox.TextChanged -= OnCountPerPageTextBoxChanged; | |
if (_jumpPageTextBox != null) | |
_jumpPageTextBox.TextChanged -= OnJumpPageTextBoxChanged; | |
if (_listBox != null) | |
_listBox.SelectionChanged -= OnSelectionChanged; | |
} | |
private void SubscribeEvents() | |
{ | |
if (_countPerPageTextBox != null) | |
_countPerPageTextBox.TextChanged += OnCountPerPageTextBoxChanged; | |
if (_jumpPageTextBox != null) | |
_jumpPageTextBox.TextChanged += OnJumpPageTextBoxChanged; | |
if (_listBox != null) | |
_listBox.SelectionChanged += OnSelectionChanged; | |
} | |
private void UpdatePages() | |
{ | |
SetValue(PagesPropertyKey, GetPagers(Count, Current)); | |
if (_listBox != null && _listBox.SelectedItem == null) | |
_listBox.SelectedItem = Current.ToString(); | |
} | |
private IEnumerable<string> GetPagers(int count, int current) | |
{ | |
if (count == 0) | |
return null; | |
if (PageCount <= 7) | |
return Enumerable.Range(1, PageCount).Select(p => p.ToString()).ToArray(); | |
if (current <= 4) | |
return new[] {"1", "2", "3", "4", "5", Ellipsis, PageCount.ToString()}; | |
if (current >= PageCount - 3) | |
return new[] | |
{ | |
"1", Ellipsis, (PageCount - 4).ToString(), (PageCount - 3).ToString(), (PageCount - 2).ToString(), | |
(PageCount - 1).ToString(), PageCount.ToString() | |
}; | |
return new[] | |
{ | |
"1", Ellipsis, (current - 1).ToString(), current.ToString(), (current + 1).ToString(), Ellipsis, | |
PageCount.ToString() | |
}; | |
} | |
} | |
} |
2) Pagination.xaml 如下:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore" | |
xmlns:helpers="clr-namespace:WPFDevelopers.Helpers" | |
xmlns:controls="clr-namespace:WPFDevelopers.Controls"> | |
<ResourceDictionary.MergedDictionaries> | |
<ResourceDictionary Source="Basic/ControlBasic.xaml"/> | |
</ResourceDictionary.MergedDictionaries> | |
<Style x:Key="PageListBoxStyleKey" TargetType="{x:Type ListBox}" | |
BasedOn="{StaticResource ControlBasicStyle}"> | |
<Setter Property="Background" Value="Transparent"/> | |
<Setter Property="BorderThickness" Value="0"/> | |
<Setter Property="Padding" Value="0"/> | |
<Setter Property="Template"> | |
<Setter.Value> | |
<ControlTemplate TargetType="{x:Type ListBox}"> | |
<Border BorderBrush="{TemplateBinding BorderBrush}" | |
BorderThickness="{TemplateBinding BorderThickness}" | |
Background="{TemplateBinding Background}" | |
SnapsToDevicePixels="True"> | |
<ScrollViewer Focusable="False" Padding="{TemplateBinding Padding}"> | |
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> | |
</ScrollViewer> | |
</Border> | |
<ControlTemplate.Triggers> | |
<Trigger Property="IsGrouping" Value="True"> | |
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/> | |
</Trigger> | |
</ControlTemplate.Triggers> | |
</ControlTemplate> | |
</Setter.Value> | |
</Setter> | |
</Style> | |
<Style x:Key="PageListBoxItemStyleKey" | |
TargetType="{x:Type ListBoxItem}" | |
BasedOn="{StaticResource ControlBasicStyle}"> | |
<Setter Property="MinWidth" Value="32"/> | |
<Setter Property="Cursor" Value="Hand"/> | |
<Setter Property="HorizontalContentAlignment" Value="Center"/> | |
<Setter Property="VerticalContentAlignment" Value="Center"/> | |
<Setter Property="helpers:ElementHelper.CornerRadius" Value="3"/> | |
<Setter Property="BorderThickness" Value="1"/> | |
<Setter Property="Padding" Value="5,0"/> | |
<Setter Property="Margin" Value="3,0"/> | |
<Setter Property="Background" Value="{DynamicResource BackgroundSolidColorBrush}"/> | |
<Setter Property="BorderBrush" Value="{DynamicResource BaseSolidColorBrush}"/> | |
<Setter Property="Template"> | |
<Setter.Value> | |
<ControlTemplate TargetType="{x:Type ListBoxItem}"> | |
<Border SnapsToDevicePixels="True" | |
Background="{TemplateBinding Background}" | |
BorderThickness="{TemplateBinding BorderThickness}" | |
BorderBrush="{TemplateBinding BorderBrush}" | |
Padding="{TemplateBinding Padding}" | |
CornerRadius="{Binding Path=(helpers:ElementHelper.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}"> | |
<ContentPresenter x:Name="PART_ContentPresenter" | |
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" | |
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" | |
RecognizesAccessKey="True" | |
TextElement.Foreground="{TemplateBinding Foreground}"/> | |
</Border> | |
</ControlTemplate> | |
</Setter.Value> | |
</Setter> | |
<Style.Triggers> | |
<DataTrigger Binding="{Binding .}" Value="···"> | |
<Setter Property="IsEnabled" Value="False"/> | |
<Setter Property="FontWeight" Value="Bold"/> | |
</DataTrigger> | |
<Trigger Property="IsMouseOver" Value="True"> | |
<Setter Property="BorderBrush" Value="{DynamicResource DefaultBorderBrushSolidColorBrush}"/> | |
<Setter Property="Background" Value="{DynamicResource DefaultBackgroundSolidColorBrush}"/> | |
<Setter Property="Foreground" Value="{DynamicResource PrimaryNormalSolidColorBrush}"/> | |
</Trigger> | |
<Trigger Property="IsSelected" Value="True"> | |
<Setter Property="Background" Value="{DynamicResource PrimaryPressedSolidColorBrush}"/> | |
<Setter Property="TextElement.Foreground" Value="{DynamicResource WindowForegroundColorBrush}"/> | |
</Trigger> | |
</Style.Triggers> | |
</Style> | |
<ControlTemplate x:Key="LitePagerControlTemplate" TargetType="{x:Type controls:Pagination}"> | |
<Border Background="{TemplateBinding Background}" | |
BorderBrush="{TemplateBinding BorderBrush}" | |
BorderThickness="{TemplateBinding BorderThickness}" | |
Padding="{TemplateBinding Padding}"> | |
<Grid> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="10"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="10"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="5"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="5"/> | |
<ColumnDefinition Width="Auto"/> | |
</Grid.ColumnDefinitions> | |
<TextBlock VerticalAlignment="Center" | |
Text="{Binding Count,StringFormat=共 {0} 条,RelativeSource={RelativeSource TemplatedParent}}"/> | |
<TextBox Grid.Column="2" x:Name="PART_CountPerPageTextBox" | |
TextAlignment="Center" VerticalContentAlignment="Center" | |
Width="60" MinWidth="0" | |
input:InputMethod.IsInputMethodEnabled="False"/> | |
<TextBlock Grid.Column="3" Text=" 条 / 页" VerticalAlignment="Center"/> | |
<Button Grid.Column="5" | |
Command="{x:Static controls:Pagination.PrevCommand}"> | |
<Path Width="7" Height="10" Stretch="Fill" | |
Fill="{Binding Foreground,RelativeSource={RelativeSource AncestorType=Button}}" | |
Data="{StaticResource PathPrevious}"/> | |
</Button> | |
<TextBox Grid.Column="7" x:Name="PART_JumpPageTextBox" | |
TextAlignment="Center" | |
VerticalContentAlignment="Center" | |
Width="60" MinWidth="0"> | |
<TextBox.ToolTip> | |
<TextBlock> | |
<TextBlock.Text> | |
<MultiBinding StringFormat="{}{0}/{1}"> | |
<Binding Path="Current" RelativeSource="{RelativeSource TemplatedParent}"/> | |
<Binding Path="PageCount" RelativeSource="{RelativeSource TemplatedParent}"/> | |
</MultiBinding> | |
</TextBlock.Text> | |
</TextBlock> | |
</TextBox.ToolTip> | |
</TextBox> | |
<Button Grid.Column="9" | |
Command="{x:Static controls:Pagination.NextCommand}"> | |
<Path Width="7" Height="10" Stretch="Fill" | |
Fill="{Binding Foreground,RelativeSource={RelativeSource AncestorType=Button}}" | |
Data="{StaticResource PathNext}"/> | |
</Button> | |
</Grid> | |
</Border> | |
</ControlTemplate> | |
<Style TargetType="{x:Type controls:Pagination}" | |
BasedOn="{StaticResource ControlBasicStyle}"> | |
<Setter Property="Template"> | |
<Setter.Value> | |
<ControlTemplate TargetType="{x:Type controls:Pagination}"> | |
<Border Background="{TemplateBinding Background}" | |
BorderBrush="{TemplateBinding BorderBrush}" | |
BorderThickness="{TemplateBinding BorderThickness}" | |
Padding="{TemplateBinding Padding}"> | |
<Grid> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="*"/> | |
<ColumnDefinition Width="Auto"/> | |
<ColumnDefinition Width="Auto"/> | |
</Grid.ColumnDefinitions> | |
<TextBlock Margin="0,0,15,0" VerticalAlignment="Center" | |
Text="{Binding Count,StringFormat=共 {0} 条,RelativeSource={RelativeSource TemplatedParent}}"/> | |
<StackPanel Grid.Column="1" Orientation="Horizontal" Margin="0,0,15,0" > | |
<TextBlock Text="每页 " VerticalAlignment="Center"/> | |
<TextBox x:Name="PART_CountPerPageTextBox" | |
TextAlignment="Center" Width="60" | |
MinWidth="0" VerticalContentAlignment="Center" | |
FontSize="{TemplateBinding FontSize}" | |
input:InputMethod.IsInputMethodEnabled="False"/> | |
<TextBlock Text=" 条" VerticalAlignment="Center"/> | |
</StackPanel> | |
<Button Grid.Column="2" | |
Command="{x:Static controls:Pagination.PrevCommand}"> | |
<Path Width="7" Height="10" Stretch="Fill" | |
Fill="{Binding Foreground,RelativeSource={RelativeSource AncestorType=Button}}" | |
Data="{StaticResource PathPrevious}"/> | |
</Button> | |
<ListBox x:Name="PART_ListBox" Grid.Column="3" | |
SelectedIndex="0" Margin="5,0" | |
ItemsSource="{TemplateBinding Pages}" | |
Style="{StaticResource PageListBoxStyleKey}" | |
ItemContainerStyle="{StaticResource PageListBoxItemStyleKey}" | |
ScrollViewer.HorizontalScrollBarVisibility="Hidden" | |
ScrollViewer.VerticalScrollBarVisibility="Hidden"> | |
<ListBox.ItemsPanel> | |
<ItemsPanelTemplate> | |
<UniformGrid Rows="1"/> | |
</ItemsPanelTemplate> | |
</ListBox.ItemsPanel> | |
</ListBox> | |
<Button Grid.Column="4" | |
Command="{x:Static controls:Pagination.NextCommand}"> | |
<Path Width="7" Height="10" Stretch="Fill" | |
Fill="{Binding Foreground,RelativeSource={RelativeSource AncestorType=Button}}" | |
Data="{StaticResource PathNext}"/> | |
</Button> | |
<StackPanel Grid.Column="5" Orientation="Horizontal"> | |
<TextBlock Text=" 前往 " VerticalAlignment="Center"/> | |
<TextBox x:Name="PART_JumpPageTextBox" | |
TextAlignment="Center" | |
ContextMenu="{x:Null}" | |
Width="60" VerticalContentAlignment="Center" | |
MinWidth="0" | |
FontSize="{TemplateBinding FontSize}" /> | |
<TextBlock Text=" 页" VerticalAlignment="Center"/> | |
</StackPanel> | |
</Grid> | |
</Border> | |
</ControlTemplate> | |
</Setter.Value> | |
</Setter> | |
<Style.Triggers> | |
<Trigger Property="IsLite" Value="true"> | |
<Setter Property="Template" Value="{StaticResource LitePagerControlTemplate}"/> | |
</Trigger> | |
</Style.Triggers> | |
</Style> | |
</ResourceDictionary> |
3) 创建PaginationExampleVM.cs如下:
using System.Collections.Generic; | |
using System.Collections.ObjectModel; | |
using System.Linq; | |
namespace WPFDevelopers.Samples.ViewModels | |
{ | |
public class PaginationExampleVM : ViewModelBase | |
{ | |
private List<int> _sourceList = new List<int>(); | |
public PaginationExampleVM() | |
{ | |
_sourceList.AddRange(Enumerable.Range(1, 300)); | |
Count = 300; | |
CurrentPageChanged(); | |
} | |
public ObservableCollection<int> PaginationCollection { get; set; } = new ObservableCollection<int>(); | |
private int _count; | |
public int Count | |
{ | |
get { return _count; } | |
set { _count = value; this.NotifyPropertyChange("Count"); CurrentPageChanged(); } | |
} | |
private int _countPerPage = 10; | |
public int CountPerPage | |
{ | |
get { return _countPerPage; } | |
set { _countPerPage = value; this.NotifyPropertyChange("CountPerPage"); CurrentPageChanged(); } | |
} | |
private int _current = 1; | |
public int Current | |
{ | |
get { return _current; } | |
set { _current = value; this.NotifyPropertyChange("Current"); CurrentPageChanged(); } | |
} | |
private void CurrentPageChanged() | |
{ | |
PaginationCollection.Clear(); | |
foreach (var i in _sourceList.Skip((Current - 1) * CountPerPage).Take(CountPerPage)) | |
{ | |
PaginationCollection.Add(i); | |
} | |
} | |
} | |
} |
4) 使用 PaginationExample.xaml 如下:
<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.PaginationExample" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers" | |
xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews" | |
mc:Ignorable="d" | |
d:DesignHeight="450" d:DesignWidth="800"> | |
<UserControl.Resources> | |
<Style TargetType="{x:Type TextBlock}"> | |
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextSolidColorBrush}" /> | |
<Setter Property="FontSize" Value="{StaticResource NormalFontSize}"/> | |
<Setter Property="VerticalAlignment" Value="Center"/> | |
</Style> | |
</UserControl.Resources> | |
<Grid> | |
<Grid.RowDefinitions> | |
<RowDefinition Height="50"/> | |
<RowDefinition/> | |
<RowDefinition Height="40"/> | |
</Grid.RowDefinitions> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="2*"/> | |
<ColumnDefinition Width="30"/> | |
<ColumnDefinition Width="*"/> | |
</Grid.ColumnDefinitions> | |
<TextBlock Text="正常模式分页" HorizontalAlignment="Center" VerticalAlignment="Center"/> | |
<TextBlock Grid.Column="2" Text="精简模式分页" HorizontalAlignment="Center" VerticalAlignment="Center"/> | |
<ListBox Grid.Row="1" Grid.Column="0" ItemsSource="{Binding NormalPaginationViewModel.PaginationCollection}" Margin="20,0,0,0"/> | |
<ListBox Grid.Row="1" Grid.Column="2" ItemsSource="{Binding LitePaginationViewModel.PaginationCollection}" Margin="0,0,20,0"/> | |
<wpfdev:Pagination Grid.Row="2" Grid.Column="0" IsLite="False" Margin="20,0,0,0" | |
Count="{Binding NormalPaginationViewModel.Count,Mode=TwoWay}" | |
CountPerPage="{Binding NormalPaginationViewModel.CountPerPage,Mode=TwoWay}" | |
Current="{Binding NormalPaginationViewModel.Current,Mode=TwoWay}"/> | |
<wpfdev:Pagination Grid.Row="2" Grid.Column="2" IsLite="true" Margin="0,0,20,0" | |
Count="{Binding LitePaginationViewModel.Count,Mode=TwoWay}" | |
CountPerPage="{Binding LitePaginationViewModel.CountPerPage,Mode=TwoWay}" | |
Current="{Binding LitePaginationViewModel.Current,Mode=TwoWay}"/> | |
</Grid> | |
</UserControl> |
5) 使用PaginationExample.xaml.cs如下:
using System.Windows.Controls; | |
using WPFDevelopers.Samples.ViewModels; | |
namespace WPFDevelopers.Samples.ExampleViews | |
{ | |
/// <summary> | |
/// PaginationExample.xaml 的交互逻辑 | |
/// </summary> | |
public partial class PaginationExample : UserControl | |
{ | |
public PaginationExampleVM NormalPaginationViewModel { get; set; } = new PaginationExampleVM(); | |
public PaginationExampleVM LitePaginationViewModel { get; set; } = new PaginationExampleVM(); | |
public PaginationExample() | |
{ | |
InitializeComponent(); | |
this.DataContext = this; | |
} | |
} | |
} |
实现效果