C#中的即时搜索
了解如何使用 ADO.NET 对象为您的 WinForms 网格创建类似 Google 的自动搜索

引言
随着新技术成为标准,用户开始在其他领域也期待这些功能。 Google 最近添加的一个功能是“边键入边搜索”。 我想为我的 WinForms 用户提供相同的功能。 经过一些反复试验后,我发现了一种我认为相当简单但功能强大的方法来模拟 Google 风格的自动搜索。 基本上,您使用 DataTable
、DataView
和视图筛选器来存储和筛选数据。 然后,我们使用 TextBox
上的 KeyUp
事件来触发筛选器。
背景
ADO.NET 提供的 数据对象非常强大,可以让我们在断开连接的环境中操作数据。 如果我们尝试使用数据库执行这种类型的操作,则每次用户添加或删除一个字母时都需要重新查询数据。 这将是一项昂贵的应用程序操作。 相反,我们可以将所有数据下载到 DataTable
中,然后与数据库断开连接。 从现在开始,将完全不会触及数据库。 相反,我们将把 DataTable
视为我们自己的内存数据库。 我们将它绑定到我们的网格,以便当我们对数据应用筛选器时,网格将自动更新以反映该筛选器。
组件
此解决方案有四个主要部分。 由于这是一篇介绍性文章,我将解释每个部分及其功能。
DataSet
–DataSet
存储一组DataTable
。 它可以存储数据关系,但这超出了本文的范围。 为了我们的目的,我们将只使用DataSet
来存储一个DataTable
。DataTable
–DataTable
包含一组数据。 它采用表格格式,但不要仅将其视为表格。 它可以是存储过程或视图的输出。DataView
– 可以将其视为针对您的DataTable
的查询平台。 我们将使用它来应用我们的筛选器。 我们也可以使用它来排序我们的数据。RowFilter
– 这是我们将在DataView
上应用的实际筛选器。 我们将根据我们的搜索框数据构建此筛选器。
代码
代码的第一部分处理数据的加载和基本视图的创建。 我创建了一个名为 ReadData
的帮助程序方法,该方法接受一个 SQL 语句并使用返回的数据填充 DataSet
。 表名称将是我们传入的名称。 然后,我在 DataSet
中根据我的 DataTable
的 DefaultView
创建一个 DataView
。 我将此 DataView
分配为我的网格(Visual Studio 附带的标准 DataGridView
)的 DataSource
。
private void Main_Load(object sender, EventArgs e)
{
//Populates the DataSet using a helper method
ReadData("SELECT * FROM adventureworks.production.vproductanddescription",
ref dstResults, "Products");
//Creates a DataView from our table's default view
myView = ((DataTable)dstResults.Tables["Products"]).DefaultView;
//Assigns the DataView to the grid
dgvResults.DataSource = myView;
}
一旦我将我的 DataView
分配给我的网格,我唯一要做的就是每当用户在搜索框中输入信息时筛选 DataView
。 这可以在 KeyUp
事件上完成。 这是该代码
//This method is fired by the KeyUp event handler on the textbox.
//The purpose of this method is to take the text from the search
//box, split it up into words, and then create and assign a filter
//statement that will do a LIKE comparison on each of the selected
//search fields. Each word's filter statement is AND'ed together
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 + "%')";
}
}
//Applies the filter to the DataView
myView.RowFilter = outputInfo;
}
这就是所有代码。 我确实将 DataSet
和 DataView
对象设置为在我表单的类级别进行范围限定,以便我可以从不同的方法访问它们。 我还使用了一些 using
语句来使代码更简洁,但仅此而已。 我已在下载中包含了完整的源代码。 示例应用程序使用 AdventureWorks
数据库。 要更改此内容,只需更改连接字符串和 SQL 语句。
总结
在本文中,我向您展示了如何使用 DataView
使用一个简单的方法创建一个可自动搜索的网格。 在一台具有 1 GB RAM 和本地版 Microsoft SQL 2008 R2 的虚拟机上进行测试时,我能够根据对三个字符串字段的搜索流畅地加载和筛选 200,000 条记录。 我能够对 500,000 条及更多记录进行操作,但性能变得明显变慢。
希望您喜欢这篇文章。 请在下方告诉我您的想法。 如果您对如何改进这一点有想法,我很乐意听取。 但请注意,我知道此代码不遵循分层、可扩展性等方面的最佳实践。 此代码的编写旨在简化和易于解释。
历史
- 2010 年 12 月 20 日 – 初始版本