C# 使用backgroundWorker在列表框中搜索

C# 使用backgroundWorker在列表框中搜索,c#,winforms,search,listbox,backgroundworker,C#,Winforms,Search,Listbox,Backgroundworker,这是一个C#WinForm问题: 我正试图在列表框中搜索。只有一个列表框装满了一些项目。在程序加载时,列表框中的所有项都会被复制到名为“tempList”的字符串类型列表中。 还有一个文本框。当用户开始键入文本框时,使用Clear()方法清除列表框。之后,将使用foreach块在tempList中搜索文本框中的单词。每个匹配项都将添加到列表框并显示给用户。 我想出了这个密码: private void textBox1_TextChanged(object sender, EventArgs e

这是一个C#WinForm问题: 我正试图在列表框中搜索。只有一个列表框装满了一些项目。在程序加载时,列表框中的所有项都会被复制到名为“tempList”的字符串类型列表中。 还有一个文本框。当用户开始键入文本框时,使用Clear()方法清除列表框。之后,将使用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);
            }
        }
    }

问题是,当用户开始在文本框中键入第一个字符时,用户界面会中断,用户必须等待搜索该字符,然后才能再次键入,每个字符都会出现这种情况。为了解决这个问题,我想我可以使用backgroundWorker。但我不明白如何在这种情况下使用它。任何有帮助的都将不胜感激

使用BackgroundWorker类

宣布

    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);
            }
        }));
    }
private void textBox1\u TextChanged(对象发送者,事件参数e)
{
RunWorkerAsync(textBox1.Text);
}
私有无效列表搜索\u DoWork(对象发送方,DoWorkEventArgs e)
{
string text=e.参数为字符串;
列表项=新列表();
foreach(模板列表中的字符串项)
{
if(item.ToLower().Contains(text.ToLower()))
{
项目。添加(项目);
}
}
e、 结果=items.ToArray();
}
私有无效列表搜索\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
字符串[]项=e。结果为字符串[];
调用((操作)(()=>
{
listBox1.Items.Clear();
foreach(项中的字符串项)
{
列表框1.Items.Add(item);
}
}));
}

使用BackgroundWorker类

宣布

    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);
            }
        }));
    }
private void textBox1\u TextChanged(对象发送者,事件参数e)
{
RunWorkerAsync(textBox1.Text);
}
私有无效列表搜索\u DoWork(对象发送方,DoWorkEventArgs e)
{
string text=e.参数为字符串;
列表项=新列表();
foreach(模板列表中的字符串项)
{
if(item.ToLower().Contains(text.ToLower()))
{
项目。添加(项目);
}
}
e、 结果=items.ToArray();
}
私有无效列表搜索\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
字符串[]项=e。结果为字符串[];
调用((操作)(()=>
{
listBox1.Items.Clear();
foreach(项中的字符串项)
{
列表框1.Items.Add(item);
}
}));
}

使用
任务
类要比
后台工作人员
简单得多

尝试以下简单的解决方案:

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;
}

使用
任务
类要比
后台工作人员
容易得多

尝试以下简单的解决方案:

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;
}

似乎您正在尝试用不同的接口复制自动完成功能。为什么不使用已经内置的UI功能呢?我想自动补全是指在用户键入文本时提示单词并附加到文本框内容的功能?不,那不是我的本意。我特别尝试在列表框中搜索文本框中键入的单词。您应该在用户离开文本框或按
enter
@Fabio后才开始搜索,这是个好主意。使用按钮并按Enter键确实在我脑海中出现,但我真的很想使用backgroundWorker并在用户键入时进行搜索。因为我在很多应用程序中都见过这种搜索方式。例如,音乐播放器“Winamp”有一个非常类似的搜索框,它非常容易使用。当我在框中键入内容时,结果会越来越被过滤,直到我看到我想要的内容并停止键入为止。我想创建这样的东西…似乎您正试图用不同的界面复制AutoComplete功能。为什么不使用已经内置的UI功能呢?我想自动补全是指在用户键入文本时提示单词并附加到文本框内容的功能?不,那不是我的本意。我特别尝试在列表框中搜索文本框中键入的单词。您应该在用户离开文本框或按
enter
@Fabio后才开始搜索,这是个好主意。使用按钮并按Enter键确实在我脑海中出现,但我真的很想使用backgroundWorker并在用户键入时进行搜索。因为我在很多应用程序中都见过这种搜索方式。例如,音乐播放器“Winamp”有一个非常类似的搜索框,它非常容易使用。当我在框中键入内容时,结果会越来越被过滤,直到我看到我想要的内容并停止键入为止。我想创造这样的东西…太棒了!这正是我想要的。非常感谢您。注意:运行辅助程序完成处理程序中的调用是多余的。我只是做了一个快速检查,运行辅助程序总是在创建后台辅助程序的同一线程上运行。所以你可以简化一点。太棒了!这正是我想要的。非常感谢您。注意:运行辅助程序完成处理程序中的调用是多余的。我只是做了一个快速检查,运行辅助程序总是在创建后台辅助程序的同一线程上运行。所以你可以简化一点。