简体   繁体   English

向单元格赋值时,DataGridView SLOW

[英]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. 我似乎无法弄清楚这里发生了什么...我有一个dataGridView,在任何给定时间不超过500行,但通常大约200或300.我遍历网格并根据用户交互设置按钮文本和颜色。 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 谢谢你,-DA

I too was changing cell values in a DataGridView and experiencing slowness. 我也在改变DataGridView中的单元格值并且经历了缓慢。 It was taking 5-6 times as long to load when I changed 2 values per row AFTER the row was inserted. 在插入行之后每行更改2个值时,加载时间为5-6倍。

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. 显然,每次在单元格中更改值时,DataGridView都会重新计算列宽,以确保所有文本都可见 - 如上面的属性所指定。 Using a stopwatch in my code, it would take about 1 second to load 400 rows with about 12 cells each. 在我的代码中使用秒表,加载400行需要大约1秒钟,每行约12个单元格。

Then I set the property to: 然后我将属性设置为:

dgv_mainlist.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;

Now my DataGridView takes about .05 seconds to load. 现在我的DataGridView加载大约需要0.05秒。 Twenty times faster! 快20倍!

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". 如果你需要像我一样将上面的autosize属性设置为“AllCells”,你可以在更改值之前将autosize设置为“None”,然后在完成后将其设置为“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. 它只增加了0.1秒的加载时间,这比将它设置为“AllCells”整个时间要好得多,这几乎加快了我的加载时间。

Credit goes to this page for helping me find the answer. 感谢您访问此页面以帮助我找到答案。

Added note: My DataGridView is not bound to a datasource. 添加注释:我的DataGridView未绑定到数据源。 Rows are inserted via loop in code. 在代码中通过循环插入行。

Set autosize mode to none. 将自动调整大小模式设置为无。

paginationGirdView.Columns["colActualTime"].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;

//assign value

row.Cells["colActualTime"].Value = "yesterday";
paginationGirdView.Columns["colActualTime"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

This will solve your stated problem. 这将解决您所述的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM