Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Winform grid rendering slow on Windows 7

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 ?

like image 256
kefeizhou Avatar asked Sep 14 '11 03:09

kefeizhou


2 Answers

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

like image 89
Seph Avatar answered Nov 13 '22 16:11

Seph


You might want to check the AutoSizeRowsMode and AutoSizeColumnsMode settings.

Sometimes AutoSizing can slow down a GUI.

like image 1
Steve Wellens Avatar answered Nov 13 '22 17:11

Steve Wellens