使用 backgroundWorker 在列表框中搜索
Searching in a listBox using backgroundWorker
这是一个 C# - WinForm 问题:
我正在尝试在列表框中搜索。只有一个 listBox 装满了一些项目。在程序加载时,listBox 中的所有项目都被复制到名为 'tempList' 的字符串类型列表中。
还有一个文本框。当用户开始在 TextBox 中键入内容时,将使用 Clear() 方法清除 listBox。之后,将使用 foreach 块在 tempList 中搜索文本框中的单词。每个匹配项都将添加到列表框并显示给用户。
我想出了这个代码:
private void textBox1_TextChanged(object sender, EventArgs e)
{
listBox1.Items.Clear();
foreach (string item in tempList)
{
if (item.ToLower().Contains(textBox1.Text.ToLower()))
{
listBox1.Items.Add(item);
}
}
}
问题是,当用户开始在文本框中输入第一个字符时,UI中断,用户必须等到搜索因为一个字符已经完成,然后他们可以再次输入,每个字符都会发生这种情况。为了解决这个问题,我发现我可以使用 backgroundWorker。但我不明白如何在这种情况下使用它。任何有用的东西将不胜感激。
使用 BackgroundWorker class...
声明...
BackgroundWorker listSearch = new BackgroundWorker();
初始化...
listSearch.DoWork += ListSearch_DoWork;
listSearch.RunWorkerCompleted += ListSearch_RunWorkerCompleted;
事件处理程序实现...
private void textBox1_TextChanged(object sender, EventArgs e)
{
listSearch.RunWorkerAsync(textBox1.Text);
}
private void ListSearch_DoWork(object sender, DoWorkEventArgs e)
{
string text = e.Argument as string;
List<string> items = new List<string>();
foreach (string item in tempList)
{
if (item.ToLower().Contains(text.ToLower()))
{
items.Add(item);
}
}
e.Result = items.ToArray();
}
private void ListSearch_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
string[] items = e.Result as string[];
Invoke((Action)(() =>
{
listBox1.Items.Clear();
foreach(string item in items)
{
listBox1.Items.Add(item);
}
}));
}
Task
class 的使用比 BackgroundWorker
容易得多。
试试这个简单的解决方案:
private async void TextBox_TextChanged(object sender, EventArgs e)
{
listBox.DataSource = null;
var task = Task.Run(() =>
{
var resultList = new List<string>();
foreach (string item in tempList)
if (item.ToLower().Contains(textBox.Text.ToLower()))
resultList.Add(item);
return resultList;
});
listBox.DataSource = await task;
}
使用数据绑定来简化代码。在程序加载时,设置
listBox.DataSource = tempList;
这是一个 C# - WinForm 问题: 我正在尝试在列表框中搜索。只有一个 listBox 装满了一些项目。在程序加载时,listBox 中的所有项目都被复制到名为 'tempList' 的字符串类型列表中。 还有一个文本框。当用户开始在 TextBox 中键入内容时,将使用 Clear() 方法清除 listBox。之后,将使用 foreach 块在 tempList 中搜索文本框中的单词。每个匹配项都将添加到列表框并显示给用户。 我想出了这个代码:
private void textBox1_TextChanged(object sender, EventArgs e)
{
listBox1.Items.Clear();
foreach (string item in tempList)
{
if (item.ToLower().Contains(textBox1.Text.ToLower()))
{
listBox1.Items.Add(item);
}
}
}
问题是,当用户开始在文本框中输入第一个字符时,UI中断,用户必须等到搜索因为一个字符已经完成,然后他们可以再次输入,每个字符都会发生这种情况。为了解决这个问题,我发现我可以使用 backgroundWorker。但我不明白如何在这种情况下使用它。任何有用的东西将不胜感激。
使用 BackgroundWorker class...
声明...
BackgroundWorker listSearch = new BackgroundWorker();
初始化...
listSearch.DoWork += ListSearch_DoWork;
listSearch.RunWorkerCompleted += ListSearch_RunWorkerCompleted;
事件处理程序实现...
private void textBox1_TextChanged(object sender, EventArgs e)
{
listSearch.RunWorkerAsync(textBox1.Text);
}
private void ListSearch_DoWork(object sender, DoWorkEventArgs e)
{
string text = e.Argument as string;
List<string> items = new List<string>();
foreach (string item in tempList)
{
if (item.ToLower().Contains(text.ToLower()))
{
items.Add(item);
}
}
e.Result = items.ToArray();
}
private void ListSearch_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
string[] items = e.Result as string[];
Invoke((Action)(() =>
{
listBox1.Items.Clear();
foreach(string item in items)
{
listBox1.Items.Add(item);
}
}));
}
Task
class 的使用比 BackgroundWorker
容易得多。
试试这个简单的解决方案:
private async void TextBox_TextChanged(object sender, EventArgs e)
{
listBox.DataSource = null;
var task = Task.Run(() =>
{
var resultList = new List<string>();
foreach (string item in tempList)
if (item.ToLower().Contains(textBox.Text.ToLower()))
resultList.Add(item);
return resultList;
});
listBox.DataSource = await task;
}
使用数据绑定来简化代码。在程序加载时,设置
listBox.DataSource = tempList;