[WPF] 自定义分页控件,可通过样式模板修改外观
演示效果:
有两个分页控件可供选择,第一种是通用分页控件Pager,输入总条数和页面大小,监听PageIndexChanged事件手动刷新数据;第二种是自动分页控件ListPager,输入数据源和页面大小,自动输出显示的数据,相比第一种页面信息等数据,前提是先拿到全部数据;
一、通用分页控件Pager
xaml:
<DockPanel Margin="10"> <pp:Pager x:Name="pager" DockPanel.Dock="Top" Margin="0 10"> <ComboBox x:Name="combo" Padding="6 0" SelectedIndex="0" BorderBrush="#D9D9D9" Foreground="#333" pp:BorderElement.CornerRadius="4" Margin="6 0" DisplayMemberPath="Value" SelectedValuePath="Key" SelectedValue="{Binding PageSize,ElementName=pager}" /> </pp:Pager> <ListBox x:Name="list" /> </DockPanel>
后台代码:
public PagerView() { InitializeComponent(); var dic = new Dictionary<Int32, String> { [10] = "10条/页", [20] = "20条/页", [30] = "30条/页", [40] = "40条/页", }; combo.ItemsSource = dic; combo.SelectedValue = 10; pager.PageIndexChanged += OnPageIndexChanged; pager.TotalCount = datas.Count(); } private void OnPageIndexChanged(Object sender, EventArgs e) { list.ItemsSource = datas.Skip((pager.PageIndex - 1) * pager.PageSize).Take(pager.PageSize); } private IEnumerable<Int32> datas = Enumerable.Range(1, 999);
Pager是内容控件,继承自ContentControl,下拉框是它的内容,下拉框选中值绑定PageSize,所以下拉框不是必要的,通过修改模块,页码数字、跳转页面等都可以不要;
默认样式模板:(其他控件的样式没放出来)
<Style TargetType="{x:Type ctrls:Pager}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ctrls:Pager}"> <StackPanel Orientation="Horizontal"> <TextBlock Foreground="#666" VerticalAlignment="Center" Margin="0 0 10 0">共 <Run Text="{Binding TotalCount,Mode=OneWay,RelativeSource={RelativeSource TemplatedParent}}" />条 </TextBlock> <Button Style="{StaticResource Styles.PageButton}" Margin="6 0" Command="{x:Static cmd:PageCommands.FirstPage}"> <Path Data="{StaticResource Pathes.FirstPage}" Stretch="Uniform" Width="12" Height="12" Fill="{TemplateBinding Foreground}" IsHitTestVisible="False" /> </Button> <Button Style="{StaticResource Styles.PageButton}" Margin="6 0" Command="{x:Static cmd:PageCommands.PrevPage}"> <Path Data="{StaticResource Pathes.PrevPage}" Stretch="Uniform" Width="12" Height="12" Fill="{TemplateBinding Foreground}" IsHitTestVisible="False" /> </Button> <ListBox Style="{StaticResource Styles.ListBox.PageNumber}" ItemsSource="{TemplateBinding PageNumbers}" /> <Button Style="{StaticResource Styles.PageButton}" Margin="6 0" Command="{x:Static cmd:PageCommands.NextPage}"> <Path Data="{StaticResource Pathes.NextPage}" Stretch="Uniform" Width="12" Height="12" Fill="{TemplateBinding Foreground}" IsHitTestVisible="False" /> </Button> <Button Style="{StaticResource Styles.PageButton}" Margin="6 0" Command="{x:Static cmd:PageCommands.LastPage}"> <Path Data="{StaticResource Pathes.LastPage}" Stretch="Uniform" Width="12" Height="12" Fill="{TemplateBinding Foreground}" IsHitTestVisible="False" /> </Button> <ContentPresenter /> <TextBlock Foreground="#666" VerticalAlignment="Center" Margin="10 0 6 0">共 <Run Text="{Binding PageCount,Mode=OneWay,RelativeSource={RelativeSource TemplatedParent}}" />页 </TextBlock> <TextBlock Foreground="#666" VerticalAlignment="Center" Margin="10 0 0 0">前往</TextBlock> <TextBox x:Name="input" Style="{DynamicResource PP.Styles.TextBox}" Foreground="{TemplateBinding Foreground}" MinWidth="50" HorizontalContentAlignment="Center" BorderBrush="#D9D9D9" attach:BorderElement.CornerRadius="4" Margin="6 0"> <TextBox.InputBindings> <KeyBinding Key="Return" Command="{x:Static cmd:PageCommands.SkipPage}" CommandParameter="{Binding Text,ElementName=input}" /> </TextBox.InputBindings> <i:Interaction.Behaviors> <ppi:TextBoxVerifyBehavior Regex="^\d*$" StopInput="True" /> </i:Interaction.Behaviors> </TextBox> <TextBlock Foreground="#666" VerticalAlignment="Center">页</TextBlock> <Button Style="{StaticResource Styles.PageButton}" Margin="16 0 0 0" Command="{x:Static cmd:PageCommands.SkipPage}" CommandParameter="{Binding Text,ElementName=input}">确定</Button> </StackPanel> </ControlTemplate> </Setter.Value> </Setter> </Style>
二、自动分页控件ListPager(如果可以把所有数据都拿下来,我更喜欢用这个)
xaml:
<DockPanel Margin="10"> <pp:ListPager x:Name="pager" DockPanel.Dock="Top" Margin="0 10"> <ComboBox x:Name="combo" Padding="6 0" SelectedIndex="0" BorderBrush="#D9D9D9" Foreground="#333" pp:BorderElement.CornerRadius="4" Margin="6 0" DisplayMemberPath="Value" SelectedValuePath="Key" SelectedValue="{Binding PageSize,ElementName=pager}" /> </pp:ListPager> <ListBox x:Name="list" ItemsSource="{Binding DisplaySource,ElementName=pager}" /> </DockPanel>
后台代码:
public ListPagerView() { InitializeComponent(); var dic = new Dictionary<Int32, String> { [10] = "10条/页", [20] = "20条/页", [30] = "30条/页", [40] = "40条/页", }; combo.ItemsSource = dic; combo.SelectedValue = 10; pager.Source = Enumerable.Range(1, 999); }
代码已上传至GitHub:https://github.com/LowPlayer/PP.Wpf