【问题标题】:Hiding multiple columns programmatically in DataGridView is very slow在 DataGridView 中以编程方式隐藏多列非常慢
【发布时间】:2018-10-06 02:18:15
【问题描述】:

我有一个大约 300 列和 80 行的 DatagridView。 每列可以是 3 种不同的类型。

有 3 个复选框负责显示/隐藏列,每个复选框对应每种列类型。

    private void HideColumns(DataGridView datagridview)
    {
        if (datagridview.DataSource == null) return;

        var watch = Stopwatch.StartNew();

        // Added this code further the comment
        Control c = datagridview;
        while (c != this)
        {
            c.SuspendLayout();
            c = c.Parent;
        }
        this.SuspendLayout();       

        CurrencyManager currencyManager = null;
        try
        {
            RemoveHandler(datagridview); // remove all the handlers to the datagridivew for performance issue
            currencyManager = (CurrencyManager)BindingContext[datagridview.DataSource];
            currencyManager.SuspendBinding();
            //datagridview.Visible = false;

            for (int i = 0; i < datagridview.Columns.Count; i++)
            {
                var column = datagridview.Columns[i];

                var itemType = datagridview.Rows[(int)OrdersAndComponentsRows.ItemType].Cells[column.Index].Value.ToString();
                if (itemType == Glossary.IndirectCOType )
                    column.Visible = IndirectCOCheckBox.Checked;
                else if (itemType == Glossary.NotAllocatedType )
                    column.Visible = NotAllocatedCheckBox.Checked;
                else 
                    column.Visible = DirectCOCheckBox.Checked;
            }
        }
        finally
        {
            //datagridview.Visible = true;
            if (currencyManager != null)
                currencyManager.ResumeBinding();
            AddHandler(datagridview);

            // Added this code further the comment
            c = datagridview;
            while (c != this)
            {
                c.ResumeLayout();
                c = c.Parent;
            }
            this.ResumeLayout();
        }

    // 3 check boxes are subscribed to this event
    private void DisplayColumn_CheckedChanged(object sender, EventArgs e)
    {
        try
        {
            Cursor = Cursors.WaitCursor;
            HideColumns(ShipCoverageDGV);
        }
        finally
        {
            Cursor = Cursors.Default;
        }
    }

问题是当我取消选中其中一个复选框时,隐藏列大约需要 50 秒。 奇怪的是,勾选复选框时,显示隐藏列大约需要 5 秒。

有没有什么操作可以更快地隐藏列?

【问题讨论】:

  • SuspendLayout()?当然还有 ResumeLayout。可能使 DGV DoubleBuffered..
  • @TaW,我已经用你的建议更新了我的帖子,但同样的问题。显示该列仍需要大约 50 秒。

标签: c# winforms user-interface datagridview


【解决方案1】:

我认为您需要弄清楚代码的哪一部分需要时间。在您的隐藏列方法中发生了很多事情。你能记下更细粒度的时间吗,比如在暂停布局与迭代列和隐藏列上花费了多少时间。一旦你知道有问题的区域,你就可以优化那个区域。我在这里假设问题陈述将是迭代所花费的时间,因为我们有 300 列并检查每一列的类型并根据它们的类型隐藏。

【讨论】:

    【解决方案2】:

    AutoSizeRowMode 设置为DisplayedHeaders 解决了这个问题。大约需要 1 秒钟。 在设置值之前,这个属性被设置为AllCells

    datagridview.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedHeaders;
    

    注意:将属性设置为 None 可将时间减少到大约 12 秒。

    包括修复在内的整个方法:

        private void HideColumns(DataGridView datagridview)
        {
            try
            {
                datagridview.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedHeaders;
    
                for (int i = 0; i < datagridview.Columns.Count; i++)
                {
                    var column = datagridview.Columns[i];
    
                    var itemType = datagridview.Rows[(int)OrdersAndComponentsRows.ItemType].Cells[column.Index].Value.ToString();
                    if (itemType == Glossary.IndirectCOType)
                        column.Visible = IndirectCOCheckBox.Checked;
                    else if (itemType == Glossary.NotAllocatedType)
                        column.Visible = NotAllocatedCheckBox.Checked;
                    else
                        column.Visible = DirectCOCheckBox.Checked;
                }
            }
            finally
            {
                datagridview.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            }
        }
    

    【讨论】:

    • 啊,这也有道理。
    猜你喜欢
    • 2013-02-18
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 2020-08-08
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    相关资源
    最近更新 更多