在现代应用程序中,用户期望能够快速地搜索和过滤数据。Google的自动搜索功能就是一个典型的例子,用户在输入搜索词时,搜索结果会即时更新。本文将介绍如何在WinForms应用程序中实现类似的功能。
ADO.NET提供的数据对象功能强大,可以在断开连接的环境中操作数据。如果尝试使用数据库来实现这种操作,每次用户添加或删除字母时都需要重新查询数据,这将是一个成本高昂的操作。相反,可以将所有数据下载到DataTable中,然后与数据库断开连接。从这一点开始,数据库将不再被触及。将把DataTable当作自己的内存数据库来处理。将把它绑定到网格上,以便当对数据应用过滤器时,网格将自动更新以反映过滤器。
这个解决方案有四个主要部分。由于这是一篇入门文章,将解释每个部分及其功能。
DataSet - DataSet存储一组DataTable。它可以存储数据关系,但这超出了本文的范围。对于目的,将只使用DataSet来存储一个DataTable。
DataTable - DataTable持有一组数据。它以表格格式存在,但不要将自己限制在将其视为表格的思考中。它可以是存储过程或视图的输出。
DataView - 将此视为对DataTable的查询平台。将使用它来应用过滤器。也可以使用它来对数据进行排序。
RowFilter - 这是将在DataView上应用的实际过滤器。将根据搜索框数据构建此过滤器。
代码的第一段处理数据的加载和基本视图的创建。创建了一个名为ReadData的帮助方法,它接受一个SQL语句并用返回的数据填充DataSet。表名将是传递的名称。然后创建了一个基于DataSet中的DataTable的DefaultView的DataView。将这个DataView分配为网格的DataSource(Visual Studio附带的标准DataGridView)。
private void Main_Load(object sender, EventArgs e)
{
// 使用帮助方法填充DataSet
ReadData(
"SELECT * FROM adventureworks.production.vproductanddescription",
ref dstResults,
"Products");
// 从表格的默认视图创建DataView
myView = ((DataTable)dstResults.Tables["Products"]).DefaultView;
// 将DataView分配给网格
dgvResults.DataSource = myView;
}
一旦将DataView分配给网格,唯一要做的就是在用户在搜索框中输入信息时过滤DataView。这可以在KeyUp事件上完成。以下是该代码:
private void txtSearch_KeyUp(object sender, KeyEventArgs e)
{
string outputInfo = "";
string[] keyWords = txtSearch.Text.Split(' ');
foreach (string word in keyWords)
{
if (outputInfo.Length == 0)
{
outputInfo = "(Name LIKE '%" + word + "%' OR ProductModel LIKE '%" + word + "%' OR Description LIKE '%" + word + "%')";
}
else
{
outputInfo += "AND (Name LIKE '%" + word + "%' OR ProductModel LIKE '%" + word + "%' OR Description LIKE '%" + word + "%')";
}
}
// 将过滤器应用于DataView
myView.RowFilter = outputInfo;
}
代码就是这样。将DataSet和DataView对象设置为在类级别上的范围,以便可以从不同的方法中访问它们。还使用了几个using语句来使代码更干净,但大概就是这样。已经在下载中包含了完整的源代码。示例应用程序使用AdventureWorks数据库。要更改此设置,只需更改连接字符串和SQL语句即可。
在本文中,向展示了如何使用DataView创建一个基本的自动搜索网格。在1 GB RAM的虚拟机上进行测试,并使用本地版本的Microsoft SQL 2008 R2,能够平滑地加载并根据三个字符串字段的搜索过滤200,000条记录。能够操作500,000条记录甚至更多,但性能明显变慢。