Search code examples
c#winformssearchlistboxbackgroundworker

Searching in a listBox using backgroundWorker


This is a C# - WinForm question: I'm trying to search in a listBox. There's ONLY ONE listBox full of some items. On program load, all the items in the listBox, get copied into a List of type string called 'tempList'. There's also a TextBox. When the user starts to type in the TextBox, the listBox gets cleared using the Clear() method. After that, the word in the textbox will be searched in the tempList using a foreach block. Every match will be added to the listBox and shown to the user. I came up with this code:

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

The problem is, that when the user starts to type into the textbox, with the FIRST character, the UI breaks and user has to wait until the search for that one character is done and then they can type again and this happens with every character. To solve this I figured out that I can use backgroundWorker. But I don't understand how to use it for this scenario. Anything helpful will be appreciated.


Solution

  • Use the BackgroundWorker class...

    declare...

        BackgroundWorker listSearch = new BackgroundWorker();
    

    initialize...

            listSearch.DoWork += ListSearch_DoWork;
            listSearch.RunWorkerCompleted += ListSearch_RunWorkerCompleted;
    

    event handler implementation...

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