5

I noticed that C# winform datagrid is quite slow on my windows 7 64bit machine. For a standard grid with 1000 rows + enough columns/text to fit the width of the screen, I see noticeable rendering delay with scrolling (ie scrolling/scrollbar movement lags by ~0.5 second instead of smooth). The grid is particularly slow when maximized to full screen and gets faster as the display size decrease.

The GUI is a straightforward setup by binding a DataTable to a DataGridView instance; I've looked into the common culprits such as double buffering and did not see much improvements. The machine is win 7 64 bit with Xeon quad-core and 2 x 23inch screens on nvidia quadro nvs 420.

Anyone have any idea why this is happening ?

kefeizhou
  • 6,234
  • 10
  • 42
  • 55
  • What do you event handlers for cell formatting etc. look like? If you spend a lot of time there, the display update might be slow. Plus AutoSize*Mode as mentioned in the first answer. – TheBlastOne Sep 14 '11 at 06:33

2 Answers2

5

Try disabling all event handlers for the grid and then see how the grid performs. If it performs fine, enable some until you get to the performance suffering. If even when there are no event handlers for the grid and it still performs slow the culprit might be AutoSizing as mentioned by Steve in his answer.

Does application performance suffer on any other machine? Could it be something related to video drivers needing to be re-installed?

Edit: I just made a test application and saw your problem, but it went away when i did double buffering? how did you do the double buffering?

see this answer: How to double buffer .NET controls on a form?

my full code, I made a DataSet with 20 columns called DataSet1, and then I made a simple Windows Form with a DataGridView:

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

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // comment out the line below for the application to lag
            SetDoubleBuffered(dataGridView1);


            for (int i = 0; i < 10000; i++)
            {
                dataSet1.DataTable1.AddDataTable1Row(GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString());
            }
        }

        public static void SetDoubleBuffered(System.Windows.Forms.Control c)
        {
            //Taxes: Remote Desktop Connection and painting
            //http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
            if (System.Windows.Forms.SystemInformation.TerminalServerSession)
                return;

            System.Reflection.PropertyInfo aProp =
                  typeof(System.Windows.Forms.Control).GetProperty(
                        "DoubleBuffered",
                        System.Reflection.BindingFlags.NonPublic |
                        System.Reflection.BindingFlags.Instance);

            aProp.SetValue(c, true, null);
        }


        private Random rand = new Random();

        private string validChars = "0123456789abcdefghijklmnopqurstuvwyz";

        private string GetRandomString()
        {
            StringBuilder builder = new StringBuilder();

            char[] c = new char[rand.Next(15,20)];
            for (int i = 0; i < c.Length; i++)
            {
                c[i] = validChars[rand.Next(0, validChars.Length - 1)];
            }

            return new string(c);
        }
    }
}

Tested with over 100,000 records each with 20 columns of varying length from 15-20

Community
  • 1
  • 1
Seph
  • 8,472
  • 10
  • 63
  • 94
  • I don't have any eventHandlers for this grid (unless you're talking about any inherited handlers). Performance is bad on other machines too, but all similar OS and hardware. – kefeizhou Sep 14 '11 at 11:53
  • Can you elaborate how you did your double buffering? I have expanded my answer to my working example that seems to work. – Seph Sep 14 '11 at 12:22
  • I have the exact same function for setting double buffering. – kefeizhou Sep 14 '11 at 13:51
  • strange, I'm at a loss then as it performs fine on my Windows 7 x64 pc (core2duo with a Radeon HD 2400 XT). Is the form inherited or anything? Have you tried making a new WinForms application and doing what I did above? Does that work fine or run poorly? – Seph Sep 14 '11 at 14:30
  • I'm test it on a new winform. The only diff I see is I'm using only DataTable and you have a DataSet. I actually get a build err on "dataSet1.DataTable1" so couldn't run exactly what you have. – kefeizhou Sep 14 '11 at 15:47
1

You might want to check the AutoSizeRowsMode and AutoSizeColumnsMode settings.

Sometimes AutoSizing can slow down a GUI.

Steve Wellens
  • 20,506
  • 2
  • 28
  • 69