C# 在DataGridView中以编程方式隐藏多列非常缓慢

C# 在DataGridView中以编程方式隐藏多列非常缓慢,c#,winforms,user-interface,datagridview,C#,Winforms,User Interface,Datagridview,我有一个DatagridView,大约有300列和80行。 每列可以有3种不同的类型 有3个复选框负责显示/隐藏列,每个复选框对应于每种列类型 private void HideColumns(DataGridView datagridview) { if (datagridview.DataSource == null) return; var watch = Stopwatch.StartNew(); // Added th

我有一个DatagridView,大约有300列和80行。 每列可以有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;
        }
    }
private void HideColumns(DataGridView DataGridView)
{
if(datagridview.DataSource==null)返回;
var watch=Stopwatch.StartNew();
//在注释中添加了此代码
控件c=datagridview;
而(c!=这个)
{
c、 SuspendLayout();
c=c.父母;
}
这个.SuspendLayout();
CurrencyManager CurrencyManager=null;
尝试
{
RemoveHandler(datagridview);//删除datagridview的所有处理程序以解决性能问题
currencyManager=(currencyManager)BindingContext[datagridview.DataSource];
currencyManager.SuspendBinding();
//datagridview.Visible=false;
for(int i=0;i
问题是,当我取消选中其中一个复选框时,隐藏列大约需要50秒。 奇怪的是,当选中复选框时,显示隐藏列大约需要5秒钟


为了更快地隐藏列,是否可以执行任何操作?

我认为您需要找出代码的哪一部分需要花费时间。隐藏列方法中发生了很多事情。您是否可以在更精细的级别上记录时间,例如挂起布局与迭代列所花费的时间d隐藏列。一旦你知道了问题所在,你就可以对其进行优化。我在这里假设,问题陈述将是迭代所花费的时间,因为我们有300个列,检查每个列的类型,并根据它们的类型进行隐藏。

我想你需要弄清楚代码的哪一部分占用了时间e、 在hide columns方法中会发生很多事情。你能在更精细的层次上记下时间吗,比如挂起布局与遍历列以及隐藏列花费了多少时间。一旦你知道了问题所在,你就可以着手优化这个问题。我假设问题陈述会我们有300列,检查每一列的类型并根据它们的类型隐藏。将
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;
        }
    }
private void HideColumns(DataGridView DataGridView)
{
尝试
{
datagridview.AutoSizeRowsMode=DataGridViewAutoSizeRowsMode.DisplayedHeaders;
for(int i=0;i
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;
        }
    }
private void HideColumns(DataGridView DataGridView)
{
尝试
{
datagridview.AutoSizeRowsMode=DataGridViewAutoSizeRowsMode.DisplayedHeaders;
for(int i=0;i