c# - Realtime filtering of listbox -
I would like to be able to filter 1000 string containing a list box, each 50 - 4000 characters in length, as well as the user type In the text box without any delay.
I am currently using a timer that updates the listbox after the occurrence of the TextChanged
textbox is not triggered in 300ms. However, it is quite jerky and the UI sometimes temporarily freezes.
What is the usual way of implementing this kind of functionality?
EDIT: I am using winforms and .NET2.
Thank you
Here is a stripped version of this code that I am currently using:
string different search-string = This.filterTextBox.Text; & Lt; String & gt; SearchStrings = New List & lt; String & gt; (Different search-strings. Split (new characters [] {';'}, string split option. RemoveEmptyEntries)); // This is a member variable that is cleared when new data is loaded in the list box, if (this.unfilteredItems.Count == 0) {foreach (this.logMessagesListBox.Items in the IMessage line) {this.unfilteredItems .Add (line); }} String Compression Component = This ICAC? String Compression Ordinary Ignore Case: String Comparin. Ordinal; & Lt; IMessage & gt; As a result filtered items = new list & lt; IMessage & gt; (); Foreign Currency (Inimassage line in this. Unfiltered items) {string message = line.ToString (); If (Search Servings TrueForL (Rep (String Item)) {Return Message Index (item, comp)> gt; = 0;})} {resultFilteredItems.Add (line); }} This.logMessagesListBox.BeginUpdate (); This.logMessagesListBox.Items.Clear (); This.logMessagesListBox.Items.AddRange (resultFilteredItems.ToArray ()); This.logMessagesListBox.EndUpdate ();
You can do two things:
-
Make the UI more sensitive with the second thread to be regarded as filtering. Really a great new technique is Reactive Extensions (Rx) which is exactly what you need.
I can give an example. I think you use WinForms? Part of your code will help.
Here's a little teaser:
Observable.Context = SynchronizationContext.Current; Var TextWorld = Observeable.Form Aven & Lt; EventAgds> (Text box 1, "text changed"); Textchanged.Throttle (300). Subscribe (ea = & gt; {// here 300 milliseconds without being removed from text, filtering removed}};
-
Make your filtering algorithm more efficient Are you filtering something with startup or something like that?
You can use all prefixes of a suffix tree or list item and create a lookup. But describe what you need and I will find something simple - yet efficient enough. The UI is very heavy if you want to show 100,000 items in the listbox, but if you only take it - say 100 - it's fast (comment. Take (100) line). If the other thread is searched then it can be made slightly better. It should be easy with RX but I have not tried to do it.
Update
Try to do something that works well with 100,000 elements, which are ~ 10 characters It uses long reactive extensions (earlier links).
In addition to this, the algorithm is naive and you can make it very fast if you want.
Private Zero Form 1_load (Object Sender, EventArgs e) {Observable.Context = SynchronizationContext.Current; Var TextWorld = Observeable.Form Aven & Lt; EventAgds> (Text box 1, "text changed"); // You can change to at least 300 so that it could change the more sensitive text. Trottle (300) Subscribe (filter); } Private Zero Filter (Event & Lt; EventArgS & gt; E) {var searchStrings = textbox1.Text.Split (new four [] {';'}, string split option. RemoveEmptyEntries); // My randstressing are your unfiltered messages string compression comp = string comparison Contentculture; // Find the result that you want here, from the line = randStrings where searchStrings.All (item = & gt; line.IndexOf (item, comp)> = 0) selection row; // very fast, but only tells you only 100 that the unemployment: // resultList = resultList.Take (100); ListBox1.BeginUpdate (); ListBox1.Items.Clear (); ListBox1.Items.AddRange (resultList.ToArray ()); ListBox1.EndUpdate (); }
Comments
Post a Comment