如何对 WPF DataGrid 进行分页? [英] How can I paginate a WPF DataGrid?

查看:32
本文介绍了如何对 WPF DataGrid 进行分页?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 wpf DataGrid 中设置分页?

How can I set paging in a wpf DataGrid?

推荐答案

上面的代码项目文章非常适合使用 ADO 表完成这项工作.虽然对于大多数应用程序来说,它可能工作得很好,并且很容易理解,但还有一种更WPF-zen-like"的方式来做到这一点,那就是使用 CollectionViews.与上面的示例相比,使用 CollectionView 的优势在于它在您将哪些数据放入网格方面更通用(并不是说您不能使该示例更通用),并且它非常适合使用通用 WPF 数据绑定模型.如果需要,它为您提供了一个支持常见操作(例如排序、分组等)的地方.

The code project article above is quite good for getting this done with ADO tables. While for most applications, it is likely to work great, and is easy to understand, there is a more "WPF-zen-like" way to do it as well, and that would be using CollectionViews. The advantage of using a CollectionView compared to the example above is that it is a bit more general in terms of what data you're putting in your grid (not that you can't make that example more general), and it fits in well with the general WPF databinding model. It gives you a place to support common operations like sorting, grouping, etc, if you need those.

我整理了一个非常简短的示例,说明绑定到 .NET 4.0 DataGrid 控件的勉强工作的 PagingCollectionView.虽然示例本身非常简单,但它至少向您展示了如何开始,因为您有一个围绕实际数据集合的代理,您可以在其上执行简单的操作,如 MoveToNextPage 和 MoveToPreviousPage.

I put together a very short example of a barely working PagingCollectionView bound to the .NET 4.0 DataGrid control. While the example itself is pretty trivial, it shows you at least how to get started, as you have a proxy around the actual collection of data on which you can execute simple operations like MoveToNextPage and MoveToPreviousPage.

这是用于 Window 事件处理和 PagingCollectionView 的 C#:

Here's the C# for both the Window event handling and the 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:

Here's the XAML for the window:

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

您可以构建此 CollectionView 以支持更多功能,有些是微不足道的,例如 MoveToLastPage 和 MoveToFirstPage,而有些则需要更多地考虑您希望它的行为方式,例如排序.希望它有帮助.

You could build out this CollectionView to support more functionality, some trivial, like MoveToLastPage and MoveToFirstPage, and some that will take some more thought about how you want it to behave, such as sorting. Hope it is helpful.

这篇关于如何对 WPF DataGrid 进行分页?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆