【问题标题】:Add thousands of columns into datagridview将数千列添加到 datagridview
【发布时间】:2012-02-27 16:24:21
【问题描述】:

我正在尝试将大量列添加到 datagridview 中,但遇到了一个具有挑战性的问题。当列数变得太大时,下面的代码会非常缓慢地添加列。这取决于size 值 - 当它小于 10000 时,我得到或多或少的好结果(添加此列数需要 2-4 秒),但是当大小增加到 15000 或更多时,添加时间不成比例总而言之,对于 30000 列,它可以达到 2 分钟,而不是我预期的 20-30 秒。所以我的问题是有可能以某种方式优化这个过程吗?

datagridview.SuspendLayout();
int size = 10000;
var columns = new DataGridViewColumn[size];
for (int i = 0; i < size; i++)
            {
                columns[i] = new DataGridViewTextBoxColumn();
                columns[i].Name = "col" + i;
                columns[i].HeaderText = "col" + i;
                columns[i].FillWeight = 0.00001f;
            }
datagridview.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
Array.ForEach(columns, item => datagridview.Columns.Add(item));
datagridview.ResumeLayout();

这就是我所做的:

    int visibleColumns = 20;
    string[] headers;
    DataGridViewColumn[] columns;
    HScrollBar hbar = new HScrollBar();

public Constructor(){
    ...
    int sizeDezired = 15000;
    int size = Math.Min(sizeDezired, visibleColumns);
    columns = new DataGridViewColumn[size];
    headers = new string[sizeDezired];
    for (int i = 0; i < size; i++)
    {
        columns[i] = new DataGridViewTextBoxColumn();
        columns[i].Name = "col" + i;
        columns[i].HeaderText = "col" + i;
        columns[i].FillWeight = 0.00001f;
    }
    for (int i = 0; i < sizeDezired;i++ )
    {
        headers[i] = "col" + i;
    }
    if (sizeDezired > size)
    {
        hbar.Maximum = sizeDezired - size;
        hbar.Minimum = 0;
        hbar.Value = 0;
    }
    hbar.Scroll += hbar_Scroll;
    ...
}

    void hbar_Scroll(object sender, ScrollEventArgs e)
    {
        for (int i = 0; i < datagridview.ColumnCount; i++)
        {
            datagridview.Columns[i].HeaderText = headers[i + e.NewValue];
        }
    }

【问题讨论】:

  • 请不要在标题前加上“C#”之类的前缀。这就是标签的用途。
  • 这段时间你的内存使用情况如何?
  • 我很想知道你为什么要在一个网格中有这么多列。
  • 问题是您试图将太多数据加载到 UI 中。没有人能同时理解这么多数据。我建议与客户/最终用户合作并确定他们实际需要什么以及他们期望什么。围绕这个设计 UI。如果他们说他们需要一切,那么他们不知道自己需要什么,或者他们需要多个组件,每个组件执行特定任务。
  • 如果是某种日历,您应该考虑创建不同的视图,例如 Outlook(月、周、日),并只显示有限的时间跨度,否则它可能会变得毫无用处。

标签: c# winforms datagridview


【解决方案1】:

我添加了这段代码:

int visibleColumns = 20;// columns that are in data grid view
string[] headers;// headers for all desired columns 
DataGridViewColumn[] columns;
HScrollBar hbar = new HScrollBar();

public Constructor(){
    ...
    int sizeDesired = 15000;
    int size = Math.Min(sizeDesired, visibleColumns);
    columns = new DataGridViewColumn[size];
    headers = new string[sizeDesired];
    for (int i = 0; i < size; i++)
    {
        columns[i] = new DataGridViewTextBoxColumn();
        columns[i].Name = "col" + i;
        columns[i].HeaderText = "col" + i;
        columns[i].FillWeight = 0.00001f;
    }
    for (int i = 0; i < sizeDesired;i++ )
    {
        headers[i] = "col" + i;
    }
    if (sizeDesired > size)
    {
        hbar.Maximum = sizeDesired - size;
        hbar.Minimum = 0;
        hbar.Value = 0;
    }
    hbar.Scroll += hbar_Scroll;
    ...
}

void hbar_Scroll(object sender, ScrollEventArgs e)
{
    for (int i = 0; i < datagridview.ColumnCount; i++)
    {
        datagridview.Columns[i].HeaderText = headers[i + e.NewValue];
    }
}

这里添加了水平滚动条以循环浏览所有不可见的列,并移动列标题以直观地“滚动”所有列(本示例中为 15000),但实际上只存在 20 列。此代码不使用任何数据绑定,只有标题发生变化,因此您需要修改 hbar_Scroll 处理程序以在单元格中显示相关数据。

【讨论】:

  • 干得好,你打败了我;我得到了几乎完全相同的答案。需要指出的一点是,这种技术可以很好地与 VirtualMode 配合使用,以防万一也有非常多的行。
  • 酷。是否有机会更新它以处理“无限”行?顺便说一句,VirtualMode 相对于这种技术有哪些优点/缺点?
【解决方案2】:

您正在寻找的技术称为分页。看下面reference

“分页是限制显示的数据量的好方法 用户一次,但也是停止大量数据的一种很好的方法 通过网络传输,保存在内存中或大 查询数据库...它解决了很多问题。

最常见的解决方案是(就像在 Google 搜索中一样)是您得到 显示页面列表,您可以浏览页面 一次向上/向下一页或单击页码。

另一种方法是让它看起来好像实际上有一个大列表,但 幕后页面,让用户感觉他们实际上是 查看一个大列表。您可以在 TFS 中看到此操作的一个示例。 您可以使用 Windows 窗体数据网格 (DataGridView) 来执行此操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多