[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

posted @ 2021-05-06 18:07  孤独成派  阅读(483)  评论(0编辑  收藏  举报