支持分頁的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>
最后,運行程序,效果基本滿意。

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