【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>

 

最后,運行程序,效果基本滿意。

 

這個類嘛,寫得不算專業,總體來說屬於娛樂層次,就給大家用來做入門學習參考吧。

 

示例源代碼下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM