-
Converging Search
My boss recently converted to Windows Vista and likes its new search function. The search starts as soon as you start typing. As you type in more characters the search is refined. Now, it's my job to replicate this function.
The good news is that I'm only searching one table. The bad news is that the table is pretty big (~100000 rows).
I read the table into a dataset when the application opens. Then I update a listview when the textbox_textchanged event fires. This is really slow and blocks keyboard entry until the search is complete. As I enter more data the search does get faster but I need a way to cancel the event if I keep typing.
Another thing that may be slowing down the listview fill is the way that I am populating it.
Code:
Dim strQry As String
Dim drDef() As DataRow
ListView1.Items.Clear()
strQry = TextBox1.Text
drDef = ds.Tables("vars").Select("myVar LIKE '" & strQry & "*'")
For Each dr As DataRow In drDef
lviVar = ListView1.Items.Add(dr("myVar").ToString)
With lviVar
.SubItems.Add(dr("desc").ToString)
.SubItems.Add(dr("sys").ToString)
End With
Next
I think that things would be faster if I used addrange but I can't figure out the conversion. This compiles but blows up at runtime.
Code:
lviVar.SubItems.AddRange(DirectCast(drDef(0)("desc"), String()))
-
Re: Converging Search
Try using a dataview and applying filters to its rowfilter property.
About the addrange, fill an array first and then apply the range to the listview. That's faster!
Code:
Dim lvitems As ListViewItem()
Dim i as integer=0
For Each dsrow As DataRow In drDef
lvitems(i) = New ListViewItem(dsrow.Item("myVar").ToString)
lvitems(i).SubItems.AddRange(New String() {dsrow.Item("desc"), _
dsrow.Item("sys")})
i+=1
Next
ListView1.Items.AddRange(lvitems)
-
Re: Converging Search
I think that I'm going to have to use threading. I was just looking over an example from Kleinma but I'm not sure that is the right direction. I was going to create a thread to do the query but I'd have to abort the existing thread before I started a new one. Seems like things could get real ugly.
Threading
-
Re: Converging Search
I forgot to click the VS 2005 button when I originally posted.
Shardox
Thanks for the input. I had to modify things a little but I think that it's a little faster. I have the follwing set to throw errors:
Implicit conversion
Late Binding
Implicit type
I think that's why your code did not work on my machine.
Code:
Dim lvItems As ListViewItem
For Each dsrow As DataRow In drDef
lvItems = New ListViewItem(dsrow.Item("f_ptid").ToString)
lvItems.SubItems.AddRange(New String() {CType(dsrow.Item("f_brief"), String), _
CType(dsrow.Item("f_sys"), String)})
lsvVars.Items.Add(lvItems)
Next
I tried the datagridview before I tried the listview. It was pretty fast but I don't like the gridview look.
-
Re: Converging Search
I think there ought to be ways to speed things up. For one thing, no matter what the person enters, you may not have to return all that many records. After all, nobody can look at more than a few rows in a ListView, so decide exactly what you HAVE to return. If you can get away with only getting the first X records, then you have a decent cheat.
Perhaps you could have two queries. One returns X records, where X is slightly more records than are visible on the screen. In most cases, the person will keep typing, so there is never a need to do more than that until X becomes larger than the total number of records (as the search narrows). In the background thread, you could do the entire query. Ideally, this would be timed so that the whole query only happened when it was needed. Not quite sure how to do that, but perhaps a very short timer before the full query began.
-
Re: Converging Search
Thanks Shaggy
I'm going to think about it over the weekend and start again on Monday.
-
Re: Converging Search
My advice: CHEAT WHENEVER POSSIBLE!!!
This is how all first person games, and anything else which is seriously time-constrained, are written. Decide what minimum amount absolutely HAS to be done for the user to think the thing is working, and do ONLY that.