【问题标题】:Speeding up DataGridView Cell Content Centering Using DefaultCellStyle使用 DefaultCellStyle 加速 DataGridView 单元格内容居中
【发布时间】:2021-07-16 03:09:41
【问题描述】:

似乎对 DataGridView 中所有单元格的中心内容调用基于列的分配非常慢。例如,使用下面的代码是很慢的:

For j As Integer = 0 To UBound(columnheaders) - 1
  datagridview1.Columns(j).SortMode = DataGridViewColumnSortMode.Automatic
  datagridview1.Columns(j).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
Next

如果上面的代码被注释掉,DataGridView 加载速度会更快,但单元格条目没有居中。因此,是否有更快的解决方法?

【问题讨论】:

  • 我很好奇没有 SortMode 的性能是什么,只是为了确保它是对齐问题?此外,问题也可能是 DefaultCellStyle 尚未初始化。如果我没记错的话,DefaultCellStyle 可能为空,但是当您尝试对其进行设置时,它会查找要抓取的 CellStyle 的层次结构。因此,由于它在链条上工作以获得起始样式,因此可能会有延迟。
  • 我确实发现处理速度较慢是由于单元格居中而不是排序顺序的设置。有趣的是,使用的居中语法似乎真正涉及通过迭代循环来居中数据。我的直觉是,到现在为止,MS 已经开发出某种在添加数据时调用单元对齐的幕后方法。

标签: c# vb.net datagridview centering


【解决方案1】:

所以我在 .Net 参考源中做了一些挖掘,我 95% 确定您的问题是 DefaultCellStyle 是一项昂贵的操作。如果您的所有列都将具有完全相同的 CellStyle,请尝试为第一列抓取一次,然后对其余列进行分配。

仅供参考,这是 DataGridViewColumn 使用的 DefaultCellStyle 属性: https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/DataGridViewBand.cs,f93400c6fe8a705f

    public virtual DataGridViewCellStyle DefaultCellStyle
    {
        get
        {
            DataGridViewCellStyle dgvcs = (DataGridViewCellStyle)this.Properties.GetObject(PropDefaultCellStyle);
            if (dgvcs == null)
            {
                dgvcs = new DataGridViewCellStyle();
                dgvcs.AddScope(this.DataGridView, 
                    this.bandIsRow ? DataGridViewCellStyleScopes.Row : DataGridViewCellStyleScopes.Column);
                this.Properties.SetObject(PropDefaultCellStyle, dgvcs);
            }
            return dgvcs;
        }
        set
        {
            DataGridViewCellStyle dgvcs = null;
            if (this.HasDefaultCellStyle)
            {
                dgvcs = this.DefaultCellStyle;
                dgvcs.RemoveScope(this.bandIsRow ? DataGridViewCellStyleScopes.Row : DataGridViewCellStyleScopes.Column);
            }
            if (value != null || this.Properties.ContainsObject(PropDefaultCellStyle))
            {
                if (value != null)
                {
                    value.AddScope(this.DataGridView, 
                        this.bandIsRow ? DataGridViewCellStyleScopes.Row : DataGridViewCellStyleScopes.Column);
                }
                this.Properties.SetObject(PropDefaultCellStyle, value);
            }
            if (((dgvcs != null && value == null) || 
                (dgvcs == null && value != null) || 
                (dgvcs != null && value != null && !dgvcs.Equals(this.DefaultCellStyle))) && this.DataGridView != null)
            {
                this.DataGridView.OnBandDefaultCellStyleChanged(this);
            }
        }
    }

如您所见,获取/设置 DefaultCellStyle 需要复杂的逻辑。

顺便说一句,你是如何构建 DataGridView 的?如果您使用的是 Visual Studio 表单设计器,则有一种方法可以设置所有列将直接继承的 DefaultCellStyle,或者直接在设计器中在各个列上设置 CellStyle - 以及排序模式,顺便说一下,我可能是错的,但我认为“自动”是默认的排序模式。

【讨论】:

  • 我填充一个数据表(DT),将列名添加到DT,然后将DGV绑定到DT作为数据源,这是填充DGV的更快方法。对于 DT 中的每一行,我还用单元格数据填充一个数组(行向量),然后简单地添加每一行。没有任何东西用于通过(行,列)位置循环遍历单元格内容,这将非常缓慢。该参考代码看起来需要做很多工作,实际上似乎触及了 DGV 中的每个单元格。必须有一种更快的方法来集中数据?
  • 好吧,如果您使用的是 DataTable,有两种方法可以处理它:不要在 DataGridView 上定义任何内容,允许 DataTable 生成它认为合适的列,或者不生成,而是定义DataGridView 上的所有 DataGridViewColumns。前者允许后期绑定,后者需要早期绑定。 docs.microsoft.com/en-us/dotnet/api/…
  • 感谢有用的 cmets。我为 DGV 设置了AutoGenerateColumns = True,并且在使用例如绑定到 DT 时myDataGridView.DataSource = myDataTable,一切都被迅速填充。
【解决方案2】:

我发现似乎是一步到位的解决方案,它使用一行语法将居中分配给整个 DataGridView:

C#:

dataGridView1.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;

VB.NET

dataGridView1.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter

处理时间也比遍历每一列的时间要短得多,就像许多论坛帖子所描述的那样。最初,我确实注意到在几篇文章中提到了RowsDefaultCellStyle 命令,但没有使用或提供.Alignment 属性。

我也在定义 DGV 后立即设置了上述命令,如下所示:

Dim datagridview1 As New DataGridView
datagridview1.Visible = False
datagridview1.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
datagridview1.AutoGenerateColumns = True

在从 DT 获取数据之前调用列居中。

【讨论】:

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