|
I have recently been doing a lot of work with the DGV control and found that its performance is severely degraded when a large amount of cells get repainted. I'm only updating the grid about once every second sometimes twice a second and as it updates it sweeps across my 19" wide screen very noticeably. (Annoying!) After a bit of experimentation and streamlining some code, I was only able to improve the DGVs performance only marginally. All formatting of the cells are done in the CellPainting handler and cells are not modified directly. The data is not bound to the control as it freely comes in from the exchange and needs to be decompressed before it is displayed. What I've tried so far: When the data comes in and is compared to the data from the previous response and a change has occurred, the individual cell is invalidated with dgv.InvalidateCell(column, row). After inserting an integer counter into the CellPainting handler it revealed that even though invalidation was made at the cell level, adjacent cells were being accessed/painted. As an example if 2 cells in the 1st column at row 2 and row 11 were invalidated, then the CellPainting handler would be triggered 10 times as indicated by the integer counter inside the handler. Likewise if the 2nd cell was at row 11 and in the 2nd column, you guessed it, the integer counter was incremented 20 times! This sounds like it could be a prediction feature of the DGV. It's as if you were to click a cell with the left mouse button, hold and drag to another point. The 1st and last cell in the selection you made corresponds to the 2 cells that were originally invalidated and as I discovered everything else in between! If on the other hand only 1 cell was in invalidated, then only that cell would trigger the CellPainting handler. At worst if the only 2 cells to get invalidated were the 1st and last in the grid, then the entire grid is repainted. The integer counter was placed after all the code that formatted the cell in the CellPainting handler. I certainly hope this is clear on how I came to my conclusion. Ok well, I've searched hi and lo and Googled till I couldn't Google no more! But I believe there might be one possibile solution and that is to call the CellPainting event directly rather than have it triggered. Unfortunately the DataGridViewCellPaintingEventArgs are Non-public members of the DGV and I don't know how to pass it when I call the CellPainting event manually. To test my theory I created 2 DataGridViewCellPaintingEventArgs global variables and initialized them inside the CellPainting handler when the form loaded by passing them back and forth within the CellPainting handler. Then I pressed a button which called the CellPainting handler twice in succession. Lo and behold and to my surprise, I got the number 2 from my integer counter!!! My question is, how do I send as CellPaintingEventArgs the cell at (row, column) when I call the CellPainting method directly as I believe this will (should) work! To a lot of you experienced programmers out there, this might sound like the wrong way of doing it, but I've run out of ideas and it appears that I would get the performance I am after from the DGV. I do like the features of the DGV and I don't want to create a grid class of my own. I glanced at some articles talking about Reflection, didn't really delve into it! So if anyone can help, it would be much appreciated! john.....
|