WPF DataGrid 分页






3.09/5 (6投票s)
添加分页到 DataGrid
↵
引言
我是 WPF 的新手,一直在寻找是否有内置的分页控件,但令我惊讶的是,我发现 WPF 中没有分页控件。我浏览了很多内容,最终在浏览了几个小时后,这篇文章对我来说像救星一样 (https://codeproject.org.cn/Articles/20463/DataView-Paging-in-WPF)。但是,我仍然需要对代码进行很多更改才能使其为我工作。所以我想写一篇文章来为我的社区节省时间。所以这就是我带来一篇关于Datagrid
上的WPF分页的文章。
我编写的分页代码非常方便,您也可以在其他情况下使用此代码。这就是我的分页控件的样子
背景
本文是对https://codeproject.org.cn/Articles/20463/DataView-Paging-in-WPF的参考。唯一的区别是我添加了一个combobox
来显示记录数并使用了 LINQ 查询。
开始吧
我的设计非常简单,我使用了一个datagrid
,一个label
,一个combobox
和几个button
来设计窗口。
这是我的Datagrid
的XAML代码的样子
<DataGrid x:Name="dataGrid" Grid.Row ="1"
HorizontalAlignment="Left" Margin="51,32,0,0"
VerticalAlignment="Top" AutoGenerateColumns="True"
CanUserSortColumns="False"
IsReadOnly="False" ColumnWidth="*" />
这是分页控件的 XAML 代码
<Button Height="23" HorizontalAlignment="Left"
Name="btnFirst" VerticalAlignment="Bottom" Width="40"
Content="<<" Click="btnFirst_Click" Opacity="0.75"/>
<Button Height="23" VerticalAlignment="Bottom"
Name="btnPrev" Width="40" Click="btnPrev_Click"
Opacity="0.75" Content="<"/>
<Label x:Name="lblpageInformation" HorizontalContentAlignment="Center"
HorizontalAlignment="Left" Height="30" Width="100"
VerticalContentAlignment="Center" VerticalAlignment="Bottom"/>
<Button Height="23" HorizontalAlignment="Right"
Name="btnNext" VerticalAlignment="Bottom" Width="40"
Content=">" Click="btnNext_Click" Opacity="0.75"/>
<Button Height="23" HorizontalAlignment="Right"
VerticalAlignment="Bottom" Width="40" Name="btnLast"
Click="btnLast_Click" Opacity="0.75" Content=">>"/>
<ComboBox x:Name="cbNumberOfRecords" HorizontalAlignment="Left"
VerticalAlignment="Bottom" Width="120" SelectedIndex="0"
SelectionChanged="cbNumberOfRecords_SelectionChanged" Opacity="0.75"/>
在代码隐藏文件中,我声明了以下变量和enum
。
因此,变量numberOfRecPerPage
的值将从combobox
中分配。
int pageIndex = 1;
private int numberOfRecPerPage;
private enum PagingMode { First = 1, Next = 2, Previous = 3, Last = 4, PageCountChange = 5 };
我使用一个具有以下字段的模型类Student
public class Student
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public uint Age { get; set; }
}
这就是我随机生成数据以填充到数据网格中的方式。
private List<object> GetData()
{
List<object> genericList = new List<object>();
Student studentObj;
Random randomObj = new Random();
for (int i = 0; i < 1000; i++)
{
studentObj = new Student();
studentObj.FirstName = "First " + i;
studentObj.MiddleName = "Middle " + i;
studentObj.LastName = "Last " + i;
studentObj.Age = (uint)randomObj.Next(1, 100);
genericList.Add(studentObj);
}
return genericList;
}
在这里,我将数据绑定到数据网格itemsource
。在这里,我使用 Linq 查询来显示基于变量numberOfRecPerPage
的记录。因此,假设最初您只想每页显示 10 条记录,使用下面的代码,您可以实现这一点
List<object> myList = GetData();
dataGrid.ItemsSource = myList.Take(numberOfRecPerPage);
int count = myList.Take(numberOfRecPerPage).Count();
lblpageInformation.Content = count + " of " + myList.Count;
如何使分页工作
因此,在单击分页按钮时,Navigate
方法将执行从一页导航到另一页或从第一页导航到最后一页的魔力。下面的代码非常简单。我使用了 LINQ 查询来完成基于分页控件单击来查询数据的全部魔力。
private void Navigate(int mode)
{
int count;
switch (mode)
{
case (int)PagingMode.Next:
btnPrev.IsEnabled = true;
btnFirst.IsEnabled = true;
if (myList.Count >= (pageIndex * numberOfRecPerPage))
{
if (myList.Skip(pageIndex *
numberOfRecPerPage).Take(numberOfRecPerPage).Count() == 0)
{
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = myList.Skip((pageIndex *
numberOfRecPerPage) - numberOfRecPerPage).Take(numberOfRecPerPage);
count = (pageIndex * numberOfRecPerPage) +
(myList.Skip(pageIndex *
numberOfRecPerPage).Take(numberOfRecPerPage)).Count();
}
else
{
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = myList.Skip(pageIndex *
numberOfRecPerPage).Take(numberOfRecPerPage);
count = (pageIndex * numberOfRecPerPage) +
(myList.Skip(pageIndex *
numberOfRecPerPage).Take(numberOfRecPerPage)).Count();
pageIndex++;
}
lblpageInformation.Content = count + " of " + myList.Count;
}
else
{
btnNext.IsEnabled = false;
btnLast.IsEnabled = false;
}
break;
case (int)PagingMode.Previous:
btnNext.IsEnabled = true;
btnLast.IsEnabled = true;
if (pageIndex > 1)
{
pageIndex -= 1;
dataGrid.ItemsSource = null;
if (pageIndex == 1)
{
dataGrid.ItemsSource = myList.Take(numberOfRecPerPage);
count = myList.Take(numberOfRecPerPage).Count();
lblpageInformation.Content = count + " of " + myList.Count;
}
else
{
dataGrid.ItemsSource = myList.Skip
(pageIndex * numberOfRecPerPage).Take(numberOfRecPerPage);
count = Math.Min(pageIndex * numberOfRecPerPage, myList.Count);
lblpageInformation.Content = count + " of " + myList.Count;
}
}
else
{
btnPrev.IsEnabled = false;
btnFirst.IsEnabled = false;
}
break;
case (int)PagingMode.First:
pageIndex = 2;
Navigate((int)PagingMode.Previous);
break;
case (int)PagingMode.Last:
pageIndex = (myList.Count / numberOfRecPerPage);
Navigate((int)PagingMode.Next);
break;
case (int)PagingMode.PageCountChange:
pageIndex = 1;
numberOfRecPerPage = Convert.ToInt32(cbNumberOfRecords.SelectedItem);
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = myList.Take(numberOfRecPerPage);
count = (myList.Take(numberOfRecPerPage)).Count();
lblpageInformation.Content = count + " of " + myList.Count;
btnNext.IsEnabled = true;
btnLast.IsEnabled = true;
btnPrev.IsEnabled = true;
btnFirst.IsEnabled = true;
break;
}
}
现在我的Navigate
方法已准备就绪。让我们继续,使其工作。哦,等等,我们没有在按钮单击时调用该方法。这是从分页按钮单击调用Navigate
方法的代码。
private void btnFirst_Click(object sender, System.EventArgs e)
{
Navigate((int)PagingMode.First);
}
private void btnNext_Click(object sender, System.EventArgs e)
{
Navigate((int)PagingMode.Next);
}
private void btnPrev_Click(object sender, System.EventArgs e)
{
Navigate((int)PagingMode.Previous);
}
private void btnLast_Click(object sender, System.EventArgs e)
{
Navigate((int)PagingMode.Last);
}
private void cbNumberOfRecords_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Navigate((int)PagingMode.PageCountChange);
}
哇!全部完成。让我们整合所有代码。这是 XAML 和代码隐藏文件的代码。
C#
代码隐藏文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace DataGridSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
int pageIndex = 1;
private int numberOfRecPerPage;
//To check the paging direction according to use selection.
private enum PagingMode
{ First = 1, Next = 2, Previous = 3, Last = 4, PageCountChange = 5 };
List<object> myList = new List<object>();
public MainWindow()
{
InitializeComponent();
cbNumberOfRecords.Items.Add("10");
cbNumberOfRecords.Items.Add("20");
cbNumberOfRecords.Items.Add("30");
cbNumberOfRecords.Items.Add("50");
cbNumberOfRecords.Items.Add("100");
cbNumberOfRecords.SelectedItem = 10;
WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
this.Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
myList = GetData();
dataGrid.ItemsSource = myList.Take(numberOfRecPerPage);
int count = myList.Take(numberOfRecPerPage).Count();
lblpageInformation.Content = count + " of " + myList.Count;
}
private List<object> GetData()
{
List<object> genericList = new List<object>();
Student studentObj;
Random randomObj = new Random();
for (int i = 0; i < 1000; i++)
{
studentObj = new Student();
studentObj.FirstName = "First " + i;
studentObj.MiddleName = "Middle " + i;
studentObj.LastName = "Last " + i;
studentObj.Age = (uint)randomObj.Next(1, 100);
genericList.Add(studentObj);
}
return genericList;
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
#region Pagination
private void btnFirst_Click(object sender, System.EventArgs e)
{
Navigate((int)PagingMode.First);
}
private void btnNext_Click(object sender, System.EventArgs e)
{
Navigate((int)PagingMode.Next);
}
private void btnPrev_Click(object sender, System.EventArgs e)
{
Navigate((int)PagingMode.Previous);
}
private void btnLast_Click(object sender, System.EventArgs e)
{
Navigate((int)PagingMode.Last);
}
private void cbNumberOfRecords_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Navigate((int)PagingMode.PageCountChange);
}
private void Navigate(int mode)
{
int count;
switch (mode)
{
case (int)PagingMode.Next:
btnPrev.IsEnabled = true;
btnFirst.IsEnabled = true;
if (myList.Count >= (pageIndex * numberOfRecPerPage))
{
if (myList.Skip(pageIndex *
numberOfRecPerPage).Take(numberOfRecPerPage).Count() == 0)
{
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = myList.Skip((pageIndex *
numberOfRecPerPage) - numberOfRecPerPage).Take(numberOfRecPerPage);
count = (pageIndex * numberOfRecPerPage) +
(myList.Skip(pageIndex *
numberOfRecPerPage).Take(numberOfRecPerPage)).Count();
}
else
{
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = myList.Skip(pageIndex *
numberOfRecPerPage).Take(numberOfRecPerPage);
count = (pageIndex * numberOfRecPerPage) +
(myList.Skip(pageIndex * numberOfRecPerPage).Take(numberOfRecPerPage)).Count();
pageIndex++;
}
lblpageInformation.Content = count + " of " + myList.Count;
}
else
{
btnNext.IsEnabled = false;
btnLast.IsEnabled = false;
}
break;
case (int)PagingMode.Previous:
btnNext.IsEnabled = true;
btnLast.IsEnabled = true;
if (pageIndex > 1)
{
pageIndex -= 1;
dataGrid.ItemsSource = null;
if (pageIndex == 1)
{
dataGrid.ItemsSource = myList.Take(numberOfRecPerPage);
count = myList.Take(numberOfRecPerPage).Count();
lblpageInformation.Content = count + " of " + myList.Count;
}
else
{
dataGrid.ItemsSource = myList.Skip
(pageIndex * numberOfRecPerPage).Take(numberOfRecPerPage);
count = Math.Min(pageIndex * numberOfRecPerPage, myList.Count);
lblpageInformation.Content = count + " of " + myList.Count;
}
}
else
{
btnPrev.IsEnabled = false;
btnFirst.IsEnabled = false;
}
break;
case (int)PagingMode.First:
pageIndex = 2;
Navigate((int)PagingMode.Previous);
break;
case (int)PagingMode.Last:
pageIndex = (myList.Count / numberOfRecPerPage);
Navigate((int)PagingMode.Next);
break;
case (int)PagingMode.PageCountChange:
pageIndex = 1;
numberOfRecPerPage = Convert.ToInt32(cbNumberOfRecords.SelectedItem);
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = myList.Take(numberOfRecPerPage);
count = (myList.Take(numberOfRecPerPage)).Count();
lblpageInformation.Content = count + " of " + myList.Count;
btnNext.IsEnabled = true;
btnLast.IsEnabled = true;
btnPrev.IsEnabled = true;
btnFirst.IsEnabled = true;
break;
}
}
#endregion
}
}
XAML
这是 XAML 代码
<Window x:Class="DataGridSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DataGridSample"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="900">
<Grid OpacityMask="#FF423535">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF85BDD6" Offset="0"/>
<GradientStop Color="#FF2F7B91" Offset="0.478"/>
<GradientStop Color="#FF4492A8" Offset="0.973"/>
<GradientStop Color="#FF72A6BF" Offset="0.227"/>
<GradientStop Color="#FF2EA4C5" Offset="0.739"/>
</LinearGradientBrush>
</Grid.Background>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Label Content="My Pagination Works" FontWeight="Bold"
FontSize="25" FontStretch="UltraExpanded"
BorderBrush="Black"/>
</StackPanel>
<DataGrid x:Name="dataGrid" Grid.Row ="1"
HorizontalAlignment="Left" Margin="51,32,0,0"
VerticalAlignment="Top" AutoGenerateColumns="True"
CanUserSortColumns="False" IsReadOnly="False"
ColumnWidth="*" />
<Grid Grid.Row="2" >
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Height="23" HorizontalAlignment="Left"
Name="btnFirst" VerticalAlignment="Bottom"
Width="40" Content="<<"
Click="btnFirst_Click" Opacity="0.75"/>
<Button Height="23" VerticalAlignment="Bottom"
Name="btnPrev" Width="40" Click="btnPrev_Click"
Opacity="0.75" Content="<"/>
<Label x:Name="lblpageInformation"
HorizontalContentAlignment="Center"
HorizontalAlignment="Left" Height="30"
Width="100" VerticalContentAlignment="Center"
VerticalAlignment="Bottom"/>
<Button Height="23" HorizontalAlignment="Right"
Name="btnNext" VerticalAlignment="Bottom"
Width="40" Content=">"
Click="btnNext_Click" Opacity="0.75"/>
<Button Height="23" HorizontalAlignment="Right"
VerticalAlignment="Bottom" Width="40"
Name="btnLast" Click="btnLast_Click"
Opacity="0.75" Content=">>"/>
<ComboBox x:Name="cbNumberOfRecords"
HorizontalAlignment="Left" VerticalAlignment="Bottom"
Width="120" SelectedIndex="0"
SelectionChanged="cbNumberOfRecords_SelectionChanged"
Opacity="0.75"/>
</StackPanel>
<Grid Grid.Row="3">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center" Margin="412,62,430,-62">
<Button Height="30" HorizontalAlignment="Center"
VerticalAlignment="Bottom" Name="btnCancel"
Width="50" Opacity="0.75"
Content="Cancel" Click="btnCancel_Click"/>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Window>
关注点
我使用 Linq 查询来查询数据并将其绑定到DataGrid itemsource
。
历史
- 文章版本 3.0