【发布时间】:2018-10-02 07:40:06
【问题描述】:
我正在尝试在 listView 中进行搜索。我尝试了两种方法,第一种是从 listView 中搜索,第二种方法是从数据库中搜索,然后用已建立的项目填充列表。我可以看到两种方式都有很长的时间来加载只有 30 条记录。我在许多教程中看到,即使在数据库或 listView 中有许多记录,它也可以快速工作并且没有任何负载。我发现在第二个示例中,当我在 listView 本身内部进行搜索时,这会出现一个问题LoadAll();,因为在每个键入的字母或数字之后,它会再次填充列表并减慢应用程序的速度。有没有什么方法可以让它工作而无需长时间加载或任何最简单的方法来做到这一点?
第一个在数据库中搜索的示例
private void usersSearch_TextChanged(object sender, EventArgs e)
{
if (usersSearch.Text != "")
{
searchUsers(usersSearch.Text.ToLower());
}
}
private void searchUsers(string searchTerm)
{
usersList.Items.Clear();
string conn = ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString;
dbConn = new MySqlConnection(conn);
string query = "SELECT id, email, username, password FROM " +
"users WHERE id LIKE '%" + searchTerm + "%' OR email LIKE '%" + searchTerm + "%' OR username LIKE '%" + searchTerm + "%'";
MySqlCommand cmd = new MySqlCommand(query, dbConn);
dbConn.Open();
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
ListViewItem item = new ListViewItem(new string[] { reader["id"].ToString(), reader["email"].ToString(), reader["username"].ToString(), reader["password"].ToString()});
usersList.Items.Add(item);
}
reader.Close();
dbConn.Close();
}
在 listView 项目中搜索的第二个示例
private void usersSearch_TextChanged(object sender, EventArgs e)
{
LoadAll(); // loads all data in list
if (usersSearch.Text != "")
{
foreach (ListViewItem item in usersList.Items)
{
bool founded = false;
string value0 = item.SubItems[0].Text;
string value1 = item.SubItems[1].Text;
string value2 = item.SubItems[2].Text;
if (value0.ToLower().Contains(usersSearch.Text.ToLower()))
{
item.Selected = true;
founded = true;
}
else if (value1.ToLower().Contains(usersSearch.Text.ToLower()))
{
item.Selected = true;
founded = true;
}
else if (value2.ToLower().Contains(usersSearch.Text.ToLower()))
{
item.Selected = true;
founded = true;
}
if (!founded) usersList.Items.Remove(item);
}
}
}
【问题讨论】:
-
如果您为用户键入的每个字符访问数据库,总会有性能成本。
-
你不能只获取一次值并将其保存在数组/列表变量中。然后从本地列表中查找,而不是每次都调用DB?
-
你在使用 DisplayMember 和 ValueMember 属性吗?
-
如果您真的想更改每个字符的结果列表,请使用第二种方法,但首先加载所有记录一次,而不是一直加载。然后保留该列表(不要从中删除内容)。使用 second 列表进行显示。要获得第二个列表,请不要一直使用
ToLower。或者根本没有。试试var secondList = new List<ListViewItem>(); foreach(var item in usersList.Items) { for(var i = 0; i < 3; i++) { if (item.SubItems[i].Text.IndexOf(usersSearch.Text, StringComparison.OrdinalIgnoreCase) >= 0) { secondList.Add(item); break; } } }。