InvalidOperationException:在调整自动填充列时无法执行此操作

Ulf*_*sen 6 .net c# datagridview winforms

我有一个形式DataGridView,我想集中的列AutoSizeModeFill与栅格ColumnHeadersHeightSizeModeAutoSize.我的问题是,如果鼠标光标在表单加载时意外地悬停在网格的左上角单元格,则应用程序会抛出一个InvalidOperationException.

这是表单加载时我应该看到的: 在此输入图像描述 (注意光标是如何悬停在左上角的单元格上).

此代码将引发异常:

static class Program
{
    [STAThread]
    static void Main()
    {
        // Make sure the mouse will hover upper left cell when the form loads:
        var form = new MyForm { StartPosition = FormStartPosition.Manual };
        form.SetDesktopLocation(Cursor.Position.X - 30, Cursor.Position.Y - 40);
        Application.Run(form);
    }

    class MyForm : Form
    {
        public MyForm()
        {
            var grid = new DataGridView { Dock = DockStyle.Fill };
            grid.Columns.Add("ColumnName", "HeaderText");
            // The form will load if I remove one of the two next lines:
            grid.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            grid.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            Controls.Add(grid);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的配置中,Visual Studio吞下异常,因此我必须从Windows资源管理器或命令提示符运行该应用程序以查看错误.

这是堆栈跟踪:

System.InvalidOperationException: This operation cannot be performed while an auto-filled column is being resized.
   at System.Windows.Forms.DataGridView.PerformLayoutPrivate(Boolean useRowShortcut, Boolean computeVisibleRows, Boolean invalidInAdjustFillingColumns, Boolean repositionEditingControl)
   at System.Windows.Forms.DataGridView.SetColumnHeadersHeightInternal(Int32 columnHeadersHeight, Boolean invalidInAdjustFillingColumns)
   at System.Windows.Forms.DataGridView.AutoResizeColumnHeadersHeight(Boolean fixedRowHeadersWidth, Boolean fixedColumnsWidth)
   at System.Windows.Forms.DataGridView.OnColumnHeadersGlobalAutoSize()
   at System.Windows.Forms.DataGridView.set_TopLeftHeaderCell(DataGridViewHeaderCell value)
   at System.Windows.Forms.DataGridView.get_TopLeftHeaderCell()
   at System.Windows.Forms.DataGridView.GetCellInternal(Int32 columnIndex, Int32 rowIndex)
   at System.Windows.Forms.DataGridView.OnCellMouseEnter(DataGridViewCellEventArgs e)
   at System.Windows.Forms.DataGridView.UpdateMouseEnteredCell(HitTestInfo hti, MouseEventArgs e)
   at System.Windows.Forms.DataGridView.OnColumnWidthChanged(DataGridViewColumnEventArgs e)
   at System.Windows.Forms.DataGridView.OnBandThicknessChanged(DataGridViewBand dataGridViewBand)
   at System.Windows.Forms.DataGridViewBand.set_ThicknessInternal(Int32 value)
   at System.Windows.Forms.DataGridView.AdjustFillingColumns()
   at System.Windows.Forms.DataGridView.ComputeLayout()
   at System.Windows.Forms.DataGridView.PerformLayoutPrivate(Boolean useRowShortcut, Boolean computeVisibleRows, Boolean invalidInAdjustFillingColumns, Boolean repositionEditingControl)
   at System.Windows.Forms.DataGridView.OnHandleCreated(EventArgs e)
   at System.Windows.Forms.Control.WmCreate(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.DataGridView.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Run Code Online (Sandbox Code Playgroud)

两个问题针对同一个问题:此处此处,但在应用建议的答案时应用程序仍然崩溃.

我是否在提供的示例中打破了某种最佳做法?有没有人遇到过这种行为并知道解决方法?

Iva*_*oev 7

这似乎是一个错误 - 代码试图访问dataGridView.TopLeftHeaderCell,这在第一次发生时实际上创建了该单元格并触发了当时不期望的一些布局操作.

考虑到所有这些,修复很简单.我们需要确保TopLeftHeaderCellDataGridView处理之前创建它,方法是添加以下行(例如在添加网格之前Controls)

var topLeftHeaderCell = grid.TopLeftHeaderCell; // Make sure TopLeftHeaderCell is created
Run Code Online (Sandbox Code Playgroud)


Mic*_*kos 5

谢谢你,Ulf,提供了展示如何重现这个的优秀示例。我的一位客户向我报告了这个错误,您的样本非常宝贵。

将 Ivan 的优秀答案更进一步,创建您自己的网格继承自DataGridView应该永久防止这个荒谬的错误。只要确保在整个应用程序中始终使用自定义网格。

public class Grid
    : DataGridView
{
    protected override void OnHandleCreated(EventArgs e)
    {
        // Touching the TopLeftHeaderCell here prevents
        // System.InvalidOperationException:
        // This operation cannot be performed while
        // an auto-filled column is being resized.

        var topLeftHeaderCell = TopLeftHeaderCell;

        base.OnHandleCreated(e);
    }
}
Run Code Online (Sandbox Code Playgroud)