【WPF】闲着没事,写了个支持数据列表分页的帮助类

支持分页的MVVM组件大家可以网上找,老周这个类只是没事写来娱乐一下的,主要是功能简单,轻量级,至少它满足了我的需求,也许还有未知的 bug 。

这个类支持对数据列表进行分页处理,原理是利用 Skip 和 Take 扩展方法,从源列表中取出某一段数据。在实例化的时候,需要提供一个 IEnumerable<T> 对象作为参数,本类会根据这个数据源来计算分页,使用参数T使其支持泛型。

        public PagabledCollection(IEnumerable<T> srcItems)
        {
            _containerItems = srcItems;
            // 总项目数
            _totalItems = _containerItems.Count();
            // 计算总页数
            ComputePages();

            CurrentPage = 1; //默认页
        }

私有字段 _containerItems 主要用来引用源数据列表,_totalItems表示所有数据的总数,CurrentPage属性表示的是当前页的索引,一般来说,分页是从第1页开始的,即当前页的索引最小值为1,最大值是总页数。

ComputePages方法用来计算总页数,代码如下:

        private void ComputePages()
        {
            int p = TotalItems / PageSize;
            if ((TotalItems % PageSize) > 0)
            {
                p++;
            }
            TotalPages = p;
            ……
        }

把数据总数除以每页显示条数(PageSize)就能得到页数,但要注意一点,就是余数的问题。比如数据总数为10,每页显示3条数据,那么 10 / 3的结果为3,余数为1,这时候,总页数应该为4,而不是3。所以上面代码在除法运算后要检查一下,如果存在余数,就把总页数加上1。

CurrentPage 属性表示当前页索引,当该属性修改后,要根实际情况从源数据列表中取出一段数据,然后用 PagedItems 属性公开。

        public int CurrentPage
        {
            get { return _currentPage; }
            set
            {
                if (_currentPage != value)
                {
                    if (value < 1) _currentPage = 1;
                    else if (value > TotalPages) _currentPage = TotalPages;
                    else _currentPage = value;
                    // 筛选内容
                    SetPagedItemsCore();
                    CheckPaging();
                    OnPropertyChanged(nameof(CurrentPage));
                }
            }
        }

上面说过,当前页索引的最小值为1,最大值为总页数,所以在set属性时要进行验证。SetPagedItemsCore

方法的功能是根据当前页索引,从源数据列表中筛选出一段数据。方法定义如下:

        private void SetPagedItemsCore()
        {
            var r = _containerItems.Skip((CurrentPage - 1) * PageSize).Take(PageSize);
            PagedItems = r;
        }

从源数据列表中取数据的开始位置 = (当前页码 - 1) * 每页显示数,要提取的数据量 = PageSize,即每页显示数量。

在使用时,直接实例化类型,并把数据源从构造函数传入,然后绑定到UI上就可以了。

            List<int> list = new List<int>();
            for(int x=1; x<= 200; x++)
            {
                list.Add(x);
            }
            PagabledCollection<int> cols = new PagabledCollection<int>(list);
            cols.PageSize = 12;
            rootlayout.DataContext = cols;

而在 XAML 文档中,直接绑定到PagabledCollection实例的各个属性即可。

    <Grid Margin="15" Name="rootlayout">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <ListBox Margin="3" ItemsSource="{Binding PagedItems}"/>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button Content="上一页" Margin="0,0,5,0" IsEnabled="{Binding CanPageUp}" Click="OnPageup"/>
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding StringFormat="第{0}页 / 共{1}页">
                        <Binding Path="CurrentPage"/>
                        <Binding Path="TotalPages"/>
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
            <Button Content="下一页" Margin="5,0,0,0" IsEnabled="{Binding CanPageDown}" Click="OnPagedown"/>
            <TextBlock Margin="3,0,0,0">每页显示条数:</TextBlock>
            <TextBox Width="30" Text="{Binding Path=PageSize,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
            <Button Content="显示全部" Click="OnShowAll" Margin="13,0,0,0"/>
        </StackPanel>
    </Grid>

最后,运行程序,效果基本满意。

这个类嘛,写得不算专业,总体来说属于娱乐层次,就给大家用来做入门学习参考吧。

示例源代码下载

时间: 2024-10-02 08:29:04

【WPF】闲着没事,写了个支持数据列表分页的帮助类的相关文章

支持数据列表分页的帮助类

[WPF]闲着没事,写了个支持数据列表分页的帮助类 支持分页的MVVM组件大家可以网上找,老周这个类只是没事写来娱乐一下的,主要是功能简单,轻量级,至少它满足了我的需求,也许还有未知的 bug . 这个类支持对数据列表进行分页处理,原理是利用 Skip 和 Take 扩展方法,从源列表中取出某一段数据.在实例化的时候,需要提供一个 IEnumerable<T> 对象作为参数,本类会根据这个数据源来计算分页,使用参数T使其支持泛型. public PagabledCollection(IEnum

闲着没事写点啥之springmvc梳理

用户通过浏览器向服务器发送请求,请求被springmvc的前端控制器dispatcherservlet拦截. dispatcherservlet拦截到请求后,会调用handlermapping处理器映射器. 处理器映射器根据请求的URL找到具体的处理器,生成处理器对象及处理器拦截器(如果有的话则生成)一并返回给dispatcherservlet. dispatcherservlet会通过返回信息选择合适的handleradapter(处理器适配器). handleradapter会调用并执行ha

闲着没事?你可以这样学学算法

对于很多码农来说,算法总是显得有那么一点高深莫测,好像是一道难以跨越的坎.造成这种现象的原因,一是因为我们对算法的了解和对自己能力的了解不够,还没入门就被吓退了,另外一个原因是,大部分人实际工作中很少用到算法,很多算法都已经被封装到函数库或接口里面了,只需要调用就行,而为了能早点完成任务,我们一般都不会去想接口里面的算法如何实现,只管调用来完成任务,顺利交差就万事大吉了. “不管用什么方法,能够完成任务就可以”,其实我觉得这种想法也是可以的,毕竟我们搞技术的都比较崇尚实用主义.但是如果我们懂得背

我在写多语言支持时用到的东西

我在写多语言支持时用到的东西 絮叨絮叨:好久不来写了,竟然支持markdown 了. 我也是在项目里的wiki 里干刚接触了一些, 来这里也试试.然后悲催的发现,mac 电脑在markdown下直接上传图片有bug @2015-08-19 20:28:13.一会试一下链接版的吧. 我们的37度手环一不小心要卖到国外去了,自然要支持多国家多语言啦. 等卖到阿拉伯世界的时候,我会再补充RTL(Right To Left)相关的内容. 本文仅涉及安卓(Android)客户端的实现, 服务器后台的部分没

IOS写一个可以支持全屏的WebView

这样来写布局 一个TitleView作为顶部搜索栏: @implementation TitleView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code [self initTilte]; } return self; } -(void)initTilte{ UITextField* field = [[UITextField al

如果写一个android支持的html文件

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/199

最近相对闲点,写个笔记2

生活 最近老婆带着孩子回老家了,我这心里也就空落落了许多,才想起,自己的乐趣与婚前怎么大相径庭.婚前想着到处看看,体验丰富而新奇的旅程,婚后觉得更贴近现实生活,乐趣本身 也源自生活本身了. 乐趣 毕业季已过,想起好几年前自己找工作时,挺辛酸,但梦想却很丰富.大多数人都会想找一个自己喜欢的行业,做自己喜欢的事情.真能这么纯粹当然是好事,但往往事与愿违. 个人看淡了,觉得工作可以是自己生活乐趣的一部分,但不能强相关自己兴趣.不要把工作搞的那么神圣,要对工作的期望放低些,对自己的生活要求放高点,完全可

[WPF]绑定到界面的数组不支持调度线程以外对其更改的办法

[原]WPF编程经常遇到一个问题: 某个数组己绑定到主界面某控件中,然后在后台程序中需要对数组增(减)数据,然后程序就会报错, 程序提示:该类型的CollectionView 不支持从调度程序线程以外的线程对其SourceCollection进行的更改. 如下图所示: 既然不能这样操作,就得想一个办法来解决,现在先把把出现错误的程序全部列出来,然后再来根据解决办法进行修改, 本测试程序先建一个学生类: using System; using System.Collections.Generic;

没事写个幻灯片玩一下,发现了一个问题

没事写个幻灯片玩了一下,开始没有问题,挺好的,后来我把页面最小化了,然后再最大化之后,整个效果就错了,应该是id为ppt的滚动距离错了,不知道怎么回事,有人碰见过类似的问题吗? <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>幻灯片</title> <style type="text/css"> *{ mar