在开发Web应用程序时,数据分页是一种常见的需求,但在Windows应用程序中,这种需求并不常见。最近,在实际工作中需要实现数据分页功能,但发现WPF中并没有现成的控件可以直接使用。因此,决定自己构建一个简单的分页控件,它可以用于DataGrid或其他数据控件。这个控件不是直接绑定到网格控件的,但可以与其他数据控件一起使用。可以在文章的第一张图片中看到这个控件的工作效果。
在设计这个解决方案时,目标是实现用户结果的分页,以避免在没有实际用途的情况下进行大量数据处理。虽然没有找到一个为WPF开发的控件(也许是因为没有进行深入的研究),但找到了一篇非常有用的文章,它成为了设计这个控件的基础。这篇文章可以在[1]找到,作者是Ben Foster。文章本身并没有开发控件,但它提供了分页类的基本接口和访问不同数据源的方法。
一个分页控件的工作原理是,当用户想要更改数据页面时,控件能够通知应用程序。此外,分页还应该执行以下任务:
此外,控件应该提供支持在XAML代码中配置控件的功能。为了实现这一点,三个必要的属性被声明为依赖属性,并可以在XAML代码中进行配置。同时,ChangeIndexEvent被重新路由为一个命令,以便由窗口或MVVM架构执行。
接下来的部分描述了如何在一个简单的应用程序中使用这个控件。
要使用示例和代码,需要以下条件:
将逐步介绍如何在Windows的代码后台使用这个控件。如源代码所示,控件的所有文件都在GridPaging文件夹中。可以将文件夹复制到项目中,或者根据愿望编译一个单独的DLL。当构建项目时,可以在工具箱中看到GridPaging控件。将其拖放到想要使用它的窗口表面上。
可以按照自己的喜好个性化控件,可以在源代码标签中看到如下所示:
要使用控件,应该实现一个自定义命令,作为与控件的通信。要实现一个命令,如代码示例中所示,需要执行以下操作:
public MainWindow()
{
InitializeComponent();
this.listorders = new List
上面的代码声明了一个命令,用于与GridPaging控件一起使用,并将其分配给控件。然后需要创建命令处理程序(在代码中命名为OnChangeIndexCommandHandler),可以在以下代码片段中看到实现:
private void OnChangeIndexCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
var pageIndex = gridPaging1.PageIndex;
var pageSize = gridPaging1.PageSize;
gridPaging1.TotalCount = this.ExecuteQueryReturnTotalItem(pageIndex, pageSize);
}
实现总是相同的,只是获取数据的方法的性质会有所不同。在代码示例中有一个用于分页MS SQL Server表的方法。
但也可以查询Oracle或其他数据库,以及实体、列表或nHibernate代码。
可以看到,在GridPaging上使用了三个属性,页面索引和页面大小。这些被用作输出参数,以通知查询获取数据所需的位置。
非常重要的是,查询还应该返回整个数据计数而不分页。这对于保持正确的总页面索引计数非常重要。也就是说,必须首先查询数据库中当前查询的总行数,然后只返回页面中的行。以下是一个MS SQL Server查询的示例:
private int ExecuteQueryReturnTotalItem(int pageIndex, int pageSize)
{
// 计算初始和最终行。
var initialRow = (pageIndex - 1) * pageSize;
var finalRow = initialRow + pageSize;
// 注意更改应用程序配置文件中的连接字符串以获取正确的连接字符串。
string connString = Properties.Settings.Default.NordConnection;
var conn = new SqlConnection(connString);
const string SqlQueryCount = "select count(OrderId) from dbo.Orders";
try
{
SqlCommand commcount = new SqlCommand(SqlQueryCount, conn);
conn.Open();
var rowCount = Convert.ToInt32(commcount.ExecuteScalar());
const string SqlQuery = @"
use Northwind;
WITH Members AS ( select ROW_NUMBER()
OVER (ORDER BY OrderID DESC) as row,
OrderDate, OrderId, ShipName, ShipPostalCode from dbo.Orders )
Select row, OrderDate, OrderId, ShipName, ShipPostalCode
FROM Members
WHERE row BETWEEN @InitialRow AND @EndRow
ORDER BY row ASC;";
SqlCommand command = new SqlCommand(SqlQuery, conn);
command.Parameters.AddWithValue("@InitialRow", initialRow);
command.Parameters.AddWithValue("@EndRow", finalRow);
var reader = command.ExecuteReader();
this.listorders = new List
控件初始化时的页面大小为500,可以通过分配PageSize属性的值为50、100、500或1000来修改它。如果想使用其他值,可以修改控件代码。可以在页面大小组合框项目中输入其他值。
在MVVM开发中使用GridPaging: GridPaging公开了PageSize、PageIndex和TotalCount作为依赖属性,以及命令ChangedIndexCommand。然后可以在控件的XAML代码中使用它们,以便与ViewModel中的属性链接。也可以直接在AXML中分配命令。
正如看到的,使用这个控件并不复杂。可以使用它来防止用户返回大量行数据。这避免了UI变得无响应或网格控件中的自动筛选器开始变慢。