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();
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With