【问题标题】:Sorting columns in DataGridView causes failure while loading new data在 DataGridView 中对列进行排序导致加载新数据时失败
【发布时间】:2026-02-06 08:50:01
【问题描述】:

我有一个自定义 DataTable 绑定到绑定到 DataGridView 的 BindingDataSource。

    private dynamic matches;
    private BindingSource bsTBAstats = new BindingSource();
    private PivotTable teamstats = new PivotTable();

    public frmTBAstatistics()
    {
        InitializeComponent();

        bsTBAstats.DataSource = teamstats;
        dgvTBAstats.DataSource = bsTBAstats;

        teamstats.Key = "key";

    }

自定义 DataTable 旨在提供类似于数据透视表的功能,使用不同方法为每列汇总源表中的数据。该代码运行良好,您可以在运行时使用上下文菜单按列更改摘要类型。但是,如果您对表格进行排序,然后尝试更改其中一种汇总类型,则当我尝试重新添加行时应用程序会失败。

为了更新表,我必须删除列(因为我可能必须更改列的 DataType),并且在某些情况下我可能会添加或删除列。我认为这可能与绑定有关,因此我在执行更新之前使用 BindingDataSource 禁用挂起绑定,但这并没有解决问题。它在 this.Rows.Add(newrow) 处失败。

是否有其他一些我应该禁用的事件正在引发,这可能会导致问题?它在某种程度上与排序有关,但我不知道如何。

    // Refresh the contents of the Summary Table
    public void Update()
    {
        // If there are no source columns, do nothing.
        if (source.Columns.Count == 0)
            return;

        // Remove any data currently in the tab
        this.Clear();
        this.Columns.Clear();

        // Add a column in the pivot table for each column in the source and match the type.
        foreach (DataColumn c in source.Columns)
        {
            // If the summary type is "Count Values" add a column for each unique value in that column.
            int summarytype = summarytypes.FirstOrDefault(x => x.Key == c.ColumnName).Value;
            if (summarytype == SummaryType.CountValues)
            {
                foreach (string value in uniquevalues(c.ColumnName))
                {
                    string columnname = c.ColumnName + "_" + value;
                    SubColumn newcolumn = new SubColumn();
                    newcolumn.ParentColumn = c.ColumnName;
                    newcolumn.ColumnName = columnname;
                    newcolumn.DataType = typeof(int);
                    this.Columns.Add(newcolumn);
                }
            }
            else
            {
                string keyname = c.ColumnName;
                DataColumn newcolumn = new DataColumn();
                newcolumn.ColumnName = keyname;
                if (summarytype == 0)
                {
                    if (c.DataType == typeof(int))
                        summarytype = SummaryType.Total;
                    else if (c.DataType == typeof(bool))
                        summarytype = SummaryType.Boolean;
                    else
                        summarytype = SummaryType.First;

                }

                if (summarytype < SummaryType.Average)
                    newcolumn.DataType = typeof(int);
                else if (summarytype == SummaryType.Average)
                    newcolumn.DataType = typeof(float);
                else
                    newcolumn.DataType = c.DataType;

                this.Columns.Add(newcolumn);
                SetSummaryType(keyname, summarytype);
            }
        }

        var uniquekeys = UniqueKeys;

        // Summarize each unique key
        foreach (string uniquekey in uniquekeys)
        {
            // Create a new container for the new row data
            DataRow newrow = this.NewRow();

            // Select all records matching the current key
            DataRow[] keyrecords = source.Select(key + "='" + uniquekey + "'");

            // For each column, add the values.
            foreach (DataColumn datacolumn in source.Columns)
            {
                string keyname = datacolumn.ColumnName;
                int summarytype = summarytypes[keyname];
                if (summarytype == SummaryType.CountValues)
                {
                    foreach (string uniquevalue in uniquevalues(keyname))
                    {
                        int count = keyrecords.Count(x => (string)x[keyname] == uniquevalue);
                        newrow[keyname + "_" + uniquevalue] = count;
                    }
                }
                else
                {
                    newrow[keyname] = Summarize(keyrecords, datacolumn);
                }
            }
            this.Rows.Add(newrow);

        }

    }

【问题讨论】:

    标签: sorting datagridview datatable bindingsource


    【解决方案1】:

    我能够通过从 BindingSource 中删除排序来解决问题

            bsTBAstats.RemoveSort();
            bsTBAstats.SuspendBinding();
            teamstats.UpdateColumn(teamstats.Columns[columnClicked].ColumnName);
            bsTBAstats.ResumeBinding();
    

    我仍然不确定我是否了解对 DataGridView 进行排序的哪些方面会影响我添加记录的能力,但我能够解决它。

    【讨论】:

    • 我一直在优化我的应用程序。而不是重建整个表,我只更改汇总类型已更改的列。在这样做时,我已经确认应用程序仅在当前排序的列被删除时才会引发异常。