为了账号安全,请及时绑定邮箱和手机立即绑定

如何对WPF DataGrid进行分页?

/ 猿问

如何对WPF DataGrid进行分页?

呼唤远方 2019-12-11 14:10:45

如何在WPF中设置分页DataGrid

查看完整描述

2 回答

?
慕仰0522570

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


我整理了一个非常简短的示例,将其绑定到.NET 4.0 DataGrid控件而无法正常工作的PagingCollectionView。尽管该示例本身很简单,但它至少向您展示了入门方法,因为您具有围绕实际数据收集的代理,可以在其上执行诸如MoveToNextPage和MoveToPreviousPage之类的简单操作。


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


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>

您可以构建此CollectionView来支持更多功能,例如琐碎的功能(例如MoveToLastPage和MoveToFirstPage),而另一些则需要更多考虑您希望其行为的方式,例如排序。希望对您有所帮助。



查看完整回答
反对 回复 2019-12-13
?
天涯尽头无女友

如果将基本类替换为ListCollectionView,则可以显着提高性能(并且可能会减少错误)-常规CollectionView使用许多不推荐使用的行为,并且不再打算按原样实例化(请参阅referencesource.microsoft.com/#PresentationFramework/框架/…)。

查看完整回答
反对 回复 2019-12-13
  • 2 回答
  • 0 关注
  • 374 浏览
我要回答

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信