【问题标题】:C# Datagridview performance suffers when hiding many rows隐藏多行时 C# Datagridview 性能受到影响
【发布时间】:2012-02-13 12:13:02
【问题描述】:

我在 C# 中制作了一个 DataGradView,它允许我折叠和展开行。 看起来像这样:

在启动时,我想折叠所有具有多个条目的客户。就像图片中显示的那样。如果customers is < 10.000 的总数效果很好 如果customer is > 10.000的总数需要几分钟去。

折叠所有客户的代码:

   int number = 0;
        int oldnumber = 0;
        int parent = 0;

        foreach (CustomDataGridViewRow row in dataGridView1.Rows)
        {
            try
            {
                number = int.Parse(row.Cells[1].Value.ToString());

                if (number != oldnumber && int.Parse(dataGridView1.Rows[row.Index + 1].Cells[1].Value.ToString()) == number)
                {
                    row.Is_expander = true;
                    parent = row.Index;

                }
                if (number == oldnumber)
                {
                    row.hide(parent);
                }
                oldnumber = number;
            }
            catch { }
        }

foreach 必须折叠的行我调用row.hide(parent),它将可见性设置为 false 并保存父索引。

为每个父行绘制一个图标

你能猜到为什么隐藏所有这些行需要这么长时间吗? 也许在每个隐藏的行屏幕再次绘制之后? 也许我在循环中做不必要或高性能的事情? 我不知道

【问题讨论】:

    标签: c# performance datagridview


    【解决方案1】:

    我猜,在 datagridview 上隐藏和显示行非常慢,原因只有微软知道。但是,将行复制到数组、在数组中操作它们并将它们复制回网格的速度非常快。这是一些代码:

    DataGridViewRow[] theRows = new DataGridViewRow[Adgv.Rows.Count];
    Adgv.Rows.CopyTo(theRows, 0);
    Adgv.Rows.Clear();
    for (int loop = 0; loop < theRows.Length; loop++) theRows[loop].Visible = false;
    Adgv.Rows.AddRange(theRows);
    

    对于 35000 行,这可以在不到一秒的时间内完成。在我的代码中,我通常有一个表达式来定义该行是隐藏还是显示,并且它在不到一秒的时间内被执行。 如果我尝试在不复制的情况下执行该操作,则需要几分钟。算了!

    【讨论】:

    • 在我尝试过的所有方法中,这个对我有用(非数据表 DatagridView)谢谢。
    • 这是唯一对我有用的东西。但是请注意,这将重置选择,因此如果您需要保留它,您必须手动存储和恢复它。
    【解决方案2】:

    您可以将VirtualModeDataGridView 一起使用,以非常有效地更新网格。见这篇文章:http://msdn.microsoft.com/en-us/library/ms171622.aspx

    如果您要渲染 > 10,000 个虚拟模式是必须的!

    【讨论】:

    • 只是设置 virtualmode = true 没有显示任何结果。顺便说一句:隐藏所有行似乎也需要成倍的时间。 2 秒内 5000 行,2 分钟内 20.000 行
    • 阅读参考文章,虚拟模式不仅仅是一个布尔属性。您必须处理触发以填充可见单元格窗口的各种事件。我创建了一个分组网格,可以使用这种方法呈现 100,000 + 行。
    • 隐藏一行时究竟会触发哪些事件?您是否隐藏或删除行?我发现删除和添加比隐藏更有效
    【解决方案3】:

    是否有必要从一开始就选择所有 10000 行。可以从1-9,10-19,20-19等开始在不同的页面中显示数据。这将提高性能并提供分页系统。为什么不能尝试修改查询?

    【讨论】:

    • 需要从一开始就全选10000行
    • 那么最好在 sp/sql 中进行计算并返回数据集并将其分配给 gridviews 数据源
    【解决方案4】:

    如果设置了自动调整大小,则网格存在问题。每次更改可见属性时,都会检查完整网格的完美尺寸。

    试试这些:

    Grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
    
    foreach (DataGridViewRow Row in Grid.Rows) 
    {
       if (......) 
       {
         Row.Visible = false;
       }
    }
    Grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
    

    【讨论】:

    • 如果它应该工作,你必须为每列执行此操作
    【解决方案5】:

    在我的情况下,更改 dataGrid1.Rows[z].Visible 属性时,dataGridView 非常慢。解决方案是暂时关闭 AutoSize:

    for (int z = 0; z < dataGridView1.Columns.Count; z++)
    { // Disabled AutoSize Mode for all columns
      dataGridView1.Columns[iRow].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    }
    
    for (int iRow = 0; iRow <= dataGridView1.RowCount; iRow++)
    { // Filtering dataGridView1
      bool bVisibleCondition = ...
      dataGridView1.Rows[iRealRow].Visible = bVisibleCondition;
    }
    
    for (int z = 0; z < dataGridView1.Columns.Count; z++)
    { // Enable AutoSize Mode for all columns
      dataGridView1.Columns[z].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      • 2010-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多