我如何分页WPF数据网格?
我怎样才能在一个WPF DataGrid
设置分页?
上面的代码项目文章非常适合使用ADO表完成此操作。 虽然对于大多数应用程序来说,它可能工作得很好,而且很容易理解,还有一种更类似于“WPF-zen”的方法,那就是使用CollectionView。 与上面的例子相比,使用CollectionView的好处在于,它在你的网格中input什么数据方面更为普遍(不是你不能使这个例子更通用),而且它适合于与一般的WPF数据绑定模型。 它给了你一个地方,支持常见的操作,如sorting,分组等,如果你需要的话。
我将放在.NET 4.0 DataGrid控件上的PagingCollectionView的一个很小的例子放在一起。 虽然示例本身非常简单,但它至less向您展示了如何开始,因为您有一个可以执行简单操作(如MoveToNextPage和MoveToPreviousPage)的实际数据集合的代理。
这里是C#的窗口事件处理和PagingCollectionView:
using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Windows; using System.Windows.Data; namespace GridPagingExample { public partial class MainWindow : Window { private readonly PagingCollectionView _cview; public MainWindow() { InitializeComponent(); this._cview = new PagingCollectionView( new List<object> { new { Animal = "Lion", Eats = "Tiger" }, new { Animal = "Tiger", Eats = "Bear" }, new { Animal = "Bear", Eats = "Oh my" }, new { Animal = "Wait", Eats = "Oh my isn't an animal" }, new { Animal = "Oh well", Eats = "Who is counting anyway" }, new { Animal = "Need better content", Eats = "For posting on stackoverflow" } }, 2 ); this.DataContext = this._cview; } private void OnNextClicked(object sender, RoutedEventArgs e) { this._cview.MoveToNextPage(); } private void OnPreviousClicked(object sender, RoutedEventArgs e) { this._cview.MoveToPreviousPage(); } } public class PagingCollectionView : CollectionView { private readonly IList _innerList; private readonly int _itemsPerPage; private int _currentPage = 1; public PagingCollectionView(IList innerList, int itemsPerPage) : base(innerList) { this._innerList = innerList; this._itemsPerPage = itemsPerPage; } public override int Count { get { if (this._innerList.Count == 0) return 0; if (this._currentPage < this.PageCount) // page 1..n-1 { return this._itemsPerPage; } else // page n { var itemsLeft = this._innerList.Count % this._itemsPerPage; if (0 == itemsLeft) { return this._itemsPerPage; // exactly itemsPerPage left } else { // return the remaining items return itemsLeft; } } } } public int CurrentPage { get { return this._currentPage; } set { this._currentPage = value; this.OnPropertyChanged(new PropertyChangedEventArgs("CurrentPage")); } } public int ItemsPerPage { get { return this._itemsPerPage; } } public int PageCount { get { return (this._innerList.Count + this._itemsPerPage - 1) / this._itemsPerPage; } } private int EndIndex { get { var end = this._currentPage * this._itemsPerPage - 1; return (end > this._innerList.Count) ? this._innerList.Count : end; } } private int StartIndex { get { return (this._currentPage - 1) * this._itemsPerPage; } } public override object GetItemAt(int index) { var offset = index % (this._itemsPerPage); return this._innerList[this.StartIndex + offset]; } public void MoveToNextPage() { if (this._currentPage < this.PageCount) { this.CurrentPage += 1; } this.Refresh(); } public void MoveToPreviousPage() { if (this._currentPage > 1) { this.CurrentPage -= 1; } this.Refresh(); } } }
这是窗口的XAML:
<Window x:Class="GridPagingExample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Grid.Row="0"> <Label Grid.Row="0" Margin="2"> <Label.Content> <Binding Path="CurrentPage"> <Binding.StringFormat>Current Page: {0}</Binding.StringFormat> </Binding> </Label.Content> </Label> <Button Content="Next" Click="OnNextClicked" Margin="2"/> <Button Content="Previous" Click="OnPreviousClicked" Margin="2"/> </StackPanel> <DataGrid ItemsSource="{Binding}" Grid.Row="1"> <DataGrid.Columns> <DataGridTextColumn Header="Animal" Width="*" Binding="{Binding Animal}"/> <DataGridTextColumn Header="Eats" Width="*" Binding="{Binding Eats}"/> </DataGrid.Columns> </DataGrid> </Grid> </Window>
你可以构build出这个CollectionView来支持更多的function,比如MoveToLastPage和MoveToFirstPage,还有一些需要更多的思考,比如sorting。 希望这是有帮助的。