Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Horrible redraw performance of the DataGridView on one of my two screens

I've actually solved this, but I'm posting it for posterity.

I ran into a very odd issue with the DataGridView on my dual-monitor system. The issue manifests itself as an EXTREMELY slow repaint of the control (like 30 seconds for a full repaint), but only when it is on one of my screens. When on the other, the repaint speed is fine.

I have an Nvidia 8800 GT with the latest non-beta drivers (175. something). Is it a driver bug? I'll leave that up in the air, since I have to live with this particular configuration. (It does not happen on ATI cards, though...)

The paint speed has nothing to do with the cell contents, and custom drawing doesn't improve the performance at all - even when just painting a solid rectangle.

I later find out that placing a ElementHost (from the System.Windows.Forms.Integration namespace) on the form corrects the problem. It doesn't have to be messed with; it just needs to be a child of the form the DataGridView is also on. It can be resized to (0, 0) as long as the Visible property is true.

I don't want to explicitly add the .NET 3/3.5 dependency to my application; I make a method to create this control at runtime (if it can) using reflection. It works, and at least it fails gracefully on machines that don't have the required library - it just goes back to being slow.

This method also lets me apply to fix while the app is running, making it easier to see what the WPF libraries are changing on my form (using Spy++).

After a lot of trial and error, I notice that enabling double buffering on the control itself (as opposed to just the form) corrects the issue!


So, you just need to make a custom class based off of DataGridView so you can enable its DoubleBuffering. That's it!

class CustomDataGridView: DataGridView {     public CustomDataGridView()     {         DoubleBuffered = true;     } } 

As long as all of my instances of the grid are using this custom version, all is well. If I ever run into a situation caused by this where I'm not able to use the subclass solution (if I don't have the code), I suppose I could try to inject that control onto the form :) (although I'll be more likely to try using reflection to force the DoubleBuffered property on from the outside to once again avoid the dependency).

It is sad that such a trivially simple thing ate up so much of my time...

like image 663
Corey Ross Avatar asked Sep 23 '08 01:09

Corey Ross


People also ask

Why is DataGridView so slow?

Slow DataGridView scrolling and renderingDataGridView can be slow not only when you add data to it, but even when the platform needs to repaint DataGridView. Slow DataGridView rendering can be fixed using so called double buffering.

What is DataGridView tool how you can use it?

The DataGridView control provides a powerful and flexible way to display data in a tabular format. You can use the DataGridView control to show read-only views of a small amount of data, or you can scale it to show editable views of very large sets of data.

How many rows can DataGridView handle?

Max value, i.e. 2,147,483,647. The DataGridView's RowCount cannot hold a number more than this because it's an integer. So, you can possibly say that limit for datagridview rows is 2 Billion.

How set DataGridView cell in Edit mode?

By default, users can edit the contents of the current DataGridView text box cell by typing in it or pressing F2. This puts the cell in edit mode if all of the following conditions are met: The underlying data source supports editing.


1 Answers

You just need to make a custom class based off of DataGridView so you can enable its DoubleBuffering. That's it!

 class CustomDataGridView: DataGridView {     public CustomDataGridView()     {         DoubleBuffered = true;     }  } 

As long as all of my instances of the grid are using this custom version, all is well. If I ever run into a situation caused by this where I'm not able to use the subclass solution (if I don't have the code), I suppose I could try to inject that control onto the form :) (although I'll be more likely to try using reflection to force the DoubleBuffered property on from the outside to once again avoid the dependency).

It is sad that such a trivially simple thing ate up so much of my time...

Note: Making the answer an answer so the question can be marked as answered

like image 194
Benoit Avatar answered Oct 03 '22 07:10

Benoit