Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataGridView SLOW when assigning value to cell

I can't seem to figure out what's going here...I have a dataGridView with no more than 500 rows at any given time but usually around 200 or 300. I iterate through the grid and set the button text and color according user interaction. Example:

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
    {
        DataGridViewButtonColumn btn;
        ContextMenuStrip ctxtStartStop;

        public Form1()
        {
            InitializeComponent();

            formatGrid();
            populateGrid();

            ctxtStartStop = new ContextMenuStrip();
            ctxtStartStop.Items.Add("START ALL");
            ctxtStartStop.Items.Add("STOP ALL");
            ctxtStartStop.ItemClicked += new ToolStripItemClickedEventHandler(ctxtMenuStrip_ItemClicked);
        }

        private void formatGrid()
        {
            btn = new DataGridViewButtonColumn();
            btn.Text = "START";
            btn.Name = "colStartStop";
            btn.HeaderText = "Start/Stop";
            btn.DefaultCellStyle.BackColor = Color.LightGreen;
            btn.DefaultCellStyle.ForeColor = Color.Black;
            btn.ReadOnly = false;
            btn.UseColumnTextForButtonValue = false;
            btn.FlatStyle = FlatStyle.Standard;
            btn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

            gridDisplay.AutoGenerateColumns = false;
            gridDisplay.AllowUserToAddRows = false;
            gridDisplay.RowHeadersVisible = false;
            gridDisplay.Columns.Add(new DataGridViewTextBoxColumn()
            {
                Name = "colSymbol",
                HeaderText = "Symbols",
                ReadOnly = true,
                AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
                MinimumWidth = 50
            });
            gridDisplay.Columns.Add(btn);

            gridDisplay.MouseClick += new MouseEventHandler(gridDisplay_MouseClick);
        }

        private void populateGrid()
        {
            for (int i = 0; i < 500; i++)
            {
                gridDisplay.Rows.Add("XYZ", "START");
            }
        }

        private void gridDisplay_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
                return;

            int rowPosition = gridDisplay.HitTest(e.X, e.Y).RowIndex;
            int colPosition = gridDisplay.HitTest(e.X, e.Y).ColumnIndex;

            if (rowPosition == -1 && colPosition == 1)
            {
                ctxtStartStop.Show(gridDisplay.PointToScreen(e.Location));
            }
        }

        private void ctxtMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem.Text == "START ALL")
            {
                ctxtStartStop.Hide();
                startAll();
            }
            else if (e.ClickedItem.Text == "STOP ALL")
            {
                ctxtStartStop.Hide();
                stopAll();
            }
        }

        private void startAll()
        {
            string action = string.Empty;
            int idx = 1;

            for (int i = 0; i < gridDisplay.Rows.Count; i++)
            {
                var btnCell = gridDisplay.Rows[i].Cells[idx];

                action = (string)btnCell.Value;

                if (action == "START")
                {
                    btnCell.Value = "STOP";
                    gridDisplay.Rows[i].Cells["colStartStop"].Style.BackColor = Color.Red;
                    gridDisplay.Rows[i].Cells["colStartStop"].Style.ForeColor = Color.White;
                }
            }
        }

        private void stopAll()
        {
            string action = string.Empty;
            int idx = 1;

            for (int i = 0; i < gridDisplay.Rows.Count; i++)
            {
                var btnCell = gridDisplay.Rows[i].Cells[idx];

                action = (string)btnCell.Value;

                if (action == "STOP")
                {
                    btnCell.Value = "START";
                    gridDisplay.Rows[i].Cells["colStartStop"].Style.BackColor = Color.LightGreen;
                    gridDisplay.Rows[i].Cells["colStartStop"].Style.ForeColor = Color.Black;
                }
            }
        }
    }
}

The funny thing is that setting the Colors works fine but when I set the Value it runs extremely slow.

Can someone please explain what I'm doing wrong here.

Thank you, -DA

like image 269
Max Eisenhardt Avatar asked Dec 13 '22 00:12

Max Eisenhardt


1 Answers

I too was changing cell values in a DataGridView and experiencing slowness. It was taking 5-6 times as long to load when I changed 2 values per row AFTER the row was inserted.

The problem for me was the following property:

dgv_mainlist.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

Evidentally the DataGridView recalculates the column widths each time a value is changed in a cell to ensure all text is visible -- as the property above specifies. Using a stopwatch in my code, it would take about 1 second to load 400 rows with about 12 cells each.

Then I set the property to:

dgv_mainlist.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;

Now my DataGridView takes about .05 seconds to load. Twenty times faster!

Of course the other option is to enter in the cell values when inserting each row, but in my case that wasn't possible.

If you need the above autosize property to be set to "AllCells" as I did, you can set the autosize to "None" before changing the values, then when done set it to "AllCells". It only added .1 seconds to my load time which was a lot better than leaving it set to "AllCells" the whole time which added almost a second to my load time.

Credit goes to this page for helping me find the answer.

Added note: My DataGridView is not bound to a datasource. Rows are inserted via loop in code.

like image 153
Joe Gayetty Avatar answered Jan 04 '23 08:01

Joe Gayetty