tags:

views:

1948

answers:

5

I'm using a System.Windows.Forms.DataGrid. It is populated with about 3000 rows and redraws very slowly. If I minimize and maximize my Form all the other controls just display but I end up watching the DataGrid redraw line by line. Everything in this DataGrid is readonly if that makes a difference.

Update:

I'm not really sure how to properly implement the CellValueNeeded() event for my project, or if it would help the performance of the DataGrid in my case.

I'm creating a User Control that contains a DataGridView (see the code bellow). When the SetProject() method is called my control is set to a specific instance of my Project class. Then the control uses a static method Informa.Data.GetProjectDataTable(Project proj) to extract a DataTable from the Project. The DataSource property of the DataGrid is then set to the returned DataTable.

This is the first time I've done anything with ADO or DataGrids, so bear with me. It looks like CellValueNeed() allows me to override how a DataGrid finds a value for one of it's cells, but in my case this a lot more complicated then the examples on MSDN. The actual source of my data is a tree structure of various Node objects, the root of which is the Project instance. Each Node can have a variable set of properties, which can also be expanded by the user at runtime. Then there is a bunch of other complexities with Nodes inheriting property values from their parent nodes, and totaling other properties from their child nodes.

Informa.Data.GetProjectDataTable() cuts through all this craziness and generates a single flat DataTable of all the properties of all the Nodes. At this point I don't care about being able to relate any change of this Table back to the original Tree structure, or updating specific parts of the table when the tree structure changes. All I want to do is display the data to the user in a DataGrid.

So do I implement CellValueNeeded() to read from the DataTable provided by the Project? I would think a DataGrid would already know how to efficiency use a DataTable as a DataSource?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Informa;

namespace Informa
{
public partial class ProjectGridControl : UserControl
{
    private Project proj;

    public ProjectGridControl()
    {
        InitializeComponent();
    }

    public void SetProject(Project proj)
    {
        this.proj = proj;
        UpdateGridControl();
    }

    public void UpdateGridControl()
    {
        if (this.proj == null)
        {
            this.dataGrid.DataSource = null;
        }
        else
        {
            //Extracts a DataTable from the project and sets it as the 
            //DataSource of the property grid
            this.dataGrid.DataSource = Informa.Data.GetProjectDataTable(proj);
        }
    }
}

}

+1  A: 

DataGridView should hanlde 3000 rows with no problems in Virtual Mode.

Make sure to set VirtualMode to true (you mentioned you tried this), and also implement CellValueNeeded properly.

Read the MSDN Walkthrough on VirtualMode for details.

Reed Copsey
A: 

Once there was a little Wolf named MacroSoft, that spend some time with Vidia the Sheep. They made slowest Text and Grid rendering on the planet and pushed all the work onto the CPU in boom year of hardware advance; all while the Sheep made sure to slow it down even further.

If I'm right, you owe a letter to the lot :-)

You are running NVidia card and their crappy drivers or similar as well as seeing MSFT refusing to fix up GDI+ to hardware accelerate along with friendly vendors (even Mono will have it done before they decide to give you some energy saving and proper hardware reuse; you know decent engineering ).

Wrap your DataGridView into a new type (ie. inherit ) and set its DoubleBuffered property to true, change the designer code to use that new type.

Visible "Line by line" rendering is how bad this industry is 2009/2010 with supercomputers on the desktop and single DLL a big company is refusing to fix but will gladly charge for having it execute even slower on Mounta-Dismounta-Vista. Jokers..

rama-jka toti
Yep setting double buffered to true seems to have fixed it. Thanks.
Eric Anastas
A: 

Do you have auto-sizing for columns turned on? I've had users experience massive slowdown in our app with as few as 10 rows because auto-sizing was enabled. Basically, one grid allowed a user to check/uncheck a box to add a row to another grid, and the second grid would experience an exponential slowdown with each added row.

After some profiling, I found it was taking ~12 seconds to add 5 rows to the second table. Finally tried turning off the auto-sizing of columns, and it's instantaneous now.

Chris Doggett
No auto sizing of both rows and columns is off. Thanks for the suggestion though.
Eric Anastas
A: 

Found the solution from this guy.... it speeds up the datagridview by 20 at least

http://rdatagridview.blogspot.com/

Sequel
A: 

The Double buffer property worked great for me! Was able to do a mass find/replace for my entire solution as well to the new grid type. Thanks a bunch!

Brian