zoukankan      html  css  js  c++  java
  • 【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>

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

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

    示例源代码下载

  • 相关阅读:
    Begin Example with Override Encoded SOAP XML Serialization
    State Machine Terminology
    How to: Specify an Alternate Element Name for an XML Stream
    How to: Publish Metadata for a WCF Service.(What is the Metadata Exchange Endpoint purpose.)
    Beginning Guide With Controlling XML Serialization Using Attributes(XmlSerializaiton of Array)
    Workflow 4.0 Hosting Extensions
    What can we do in the CacheMetaData Method of Activity
    How and Why to use the System.servicemodel.MessageParameterAttribute in WCF
    How to: Begin Sample with Serialization and Deserialization an Object
    A Test WCF Service without anything of config.
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/5557216.html
Copyright © 2011-2022 走看看