Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Realtime filtering of listbox

I would like to be able to filter a listbox containing 1000 strings, each 50 - 4000 characters in length, as the user types in the textbox without a delay.

I'm currently using a timer which updates the listbox after the TextChanged event of the textbox has not been triggered in 300ms. However, this is quite jerky and the ui sometimes freezes momentarily.

What is the normal way of implementing functionality similar to this?

Edit: I'm using winforms and .net2.

Thanks

Here is a stripped down version of the code I am currently using:

string separatedSearchString = this.filterTextBox.Text;

List<string> searchStrings = new List<string>(separatedSearchString.Split(new char[] { ';' }, 
                                              StringSplitOptions.RemoveEmptyEntries));

//this is a member variable which is cleared when new data is loaded into the listbox
if (this.unfilteredItems.Count == 0)
{
    foreach (IMessage line in this.logMessagesListBox.Items)
    {
        this.unfilteredItems.Add(line);
    }
}

StringComparison comp = this.IsCaseInsensitive
                        ? StringComparison.OrdinalIgnoreCase
                        : StringComparison.Ordinal;

List<IMessage> resultingFilteredItems = new List<IMessage>();

foreach (IMessage line in this.unfilteredItems)
{
    string message = line.ToString();
    if(searchStrings.TrueForAll(delegate(string item) { return message.IndexOf(item, comp) >= 0; }))
    {
        resultingFilteredItems.Add(line);
    }
}

this.logMessagesListBox.BeginUpdate();
this.logMessagesListBox.Items.Clear();
this.logMessagesListBox.Items.AddRange(resultingFilteredItems.ToArray());
this.logMessagesListBox.EndUpdate();
like image 714
Ryan Avatar asked Oct 15 '22 02:10

Ryan


1 Answers

Azerax's answer is the right one with the new release of RX.

When you want to seperate the code from the UI elements, you can have:

input.ObserveOn(SynchronizationContext.Current).Subscribe(filterHandler, errorMsg); 

This will bring the notification back to the UI thread. Otherwise, the throttle(*) will not effect.

like image 80
Mellon Avatar answered Oct 18 '22 23:10

Mellon