views:

522

answers:

5

Hi peeps,

On my form there is a datagridview that may get upwards to about 70k items depending on how scan happy our customers get. I also have a textbox which allows the user to search the datagridview using the textchanged event. I'm using a select statement with the like clause and filling the dataset. I dont think this will cut it, because the program hangs and gets laggy when there is a large amount of records. Whats the best way I can do this if performance is a top priority?

A: 

The obvious way to improve performance is to filter at the click of a button instead of the textchanged event which gets called often.

If you don't want to change the way it works, another option would be to not start the search until a number of characters are typed, and then wait at least x seconds before firing another search.

Meta-Knight
I think this may be the best option.
broke
I faced the same problem in the past with a filter on a TextChanged event. I simply decided to go with a button instead.
Meta-Knight
+1  A: 

The best way i've found is to actually run the SQL query on another thread, store the dataset in memory, and have a timer going adding perhaps 10 records per millisecond. This way the UI still fills up, but the main processor isn't busy drawing the whole time and your user can still type. This can be scaled up and down depending on the computers its running on. I've done this with Listboxes and combo boxes and its fairly simple (if you count using delegates and invokes as simple).

This should give you the performance you desire... that is, if you have time enough to implement it.

~~~~~~~~~~~~~~~~~~~~Edit~~~~~~~~~~~~~~~~~~~~

If you wish, I could potentially post the sample code for the listbox version of this since I haven't actually seen anyone else on the net do it.

Jrud
Is there anywhere you have implemented this for a datagridview? I'm interested in implementing this for a previous project that can return up to 20k records that takes a bit to run. A link to code will suffice. Thanks!
Stevoni
Sorry, I do not have this code for a datagridview. I only have it for list boxes and combo boxes. I can send you those to pick through and you can change which control type it inherits from, and rewrite my buffer/addrow/and clear code to implement it for a datagridview.
Jrud
That'd be great, can you get my e-mail from my profile and send me the code?
Stevoni
A: 

Why return all the records? Implement server-side paging, so only 10/20/50/100 (let the user decide) records are returned at a time.

Nick
I guess because DataGridViews natively fill faster than other controls, I'm not worried about the amount of records being selected. I was hoping that once all the data was selected and put into the dataset, i could search the dataset if thats a possibility.
broke
There is a .SELECT command on a datatable I believe... perhaps that is what you are after?
Jrud
But that won't fix your lagging issue... its not the act of pulling the data across the network that is usually time consuming, its the act of drawing the records and prebuffering them that is usually the bottleneck.
Jrud
+1  A: 

If you aren't worried about the number of records being selected, just download the entire dataset.

Create a dataview object on your filled table.

Set the DataGridView.DataSource = your dataview object.

Then, instead of using the textbox's textchanged event to fill the dataset, use it to change the .RowFilter property on your dataview.

tbs
Could you elaborate on this a little more?
broke
tbs
okay ill try it out. Thanks
broke
+1  A: 

To elaborate on Meta-Knights answer: I had an issue similiar to yours and decided to go with a timer that started whenever the user typed a key. I had it set for 2 seconds because my users were usually reading information as they were typing. It seems to work pretty well and the users are very happy with the auto-searching feature.

Essentially the pseudo-code is as follows:

Sub TextChanged()  
   MyTimer.Enabled= TextBox.TextLength > 0  
End Sub

Sub TimerTick()  
   MyTimer.Enabled=False  
   Lookup(TextBox.Text)  
   MyTimer.Enabled=True  
End Sub
Stevoni