C# DataGridView更改AutoSizeRowsMode引发异常

C# DataGridView更改AutoSizeRowsMode引发异常,c#,.net,winforms,datagridview,C#,.net,Winforms,Datagridview,如果dgv当前具有AutoSizeRowsMode=DisplayedCells,则设置为“无”会导致异常 下面是重现该问题的代码。要引起异常,只需单击其中一个列标题。即使某些行可见,也会发生异常。但是,如果窗体的大小调整得足够大,则异常将停止发生。使用.NET35.NET40和.NET45进行测试 查看MSDN上DataGridView的源代码: RestoreRowsCachedHickness在每一行中循环并设置:dataGridViewRow.ThicknessInternal=data

如果dgv当前具有AutoSizeRowsMode=DisplayedCells,则设置为“无”会导致异常

下面是重现该问题的代码。要引起异常,只需单击其中一个列标题。即使某些行可见,也会发生异常。但是,如果窗体的大小调整得足够大,则异常将停止发生。使用.NET35.NET40和.NET45进行测试

查看MSDN上DataGridView的源代码:

RestoreRowsCachedHickness在每一行中循环并设置:dataGridViewRow.ThicknessInternal=dataGridViewRow.CachedHickness

DataGridViewBand.ThicknessInternal属性不检查值是否实际不同,它始终激发OnBandThicknessChanged事件

这会触发一个事件,该事件调用其他两个方法,最终到达终点:

    private void OnRowGlobalAutoSize(int rowIndex)
    {
        DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
//...
    }
奇怪的是,RowCollection抛出了一个索引越界异常

有没有合理的方法来处理这个异常错误?除了将其包装在try-catch语句中之外?

在设置AutoSizeRowsMode属性之前调用LoopThroughRowsdgv。DataGridView不必创建行,也不会创建行。通过行循环强制创建每一行并防止异常

可能在发布模式下,优化器可能会删除代码,从而删除属性

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization | System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static void LoopThroughRows(DataGridView dgv) {
    DataGridViewRowCollection rows = dgv.Rows;
    for (int i = rows.Count - 1; i >= 0; i--) {
        DataGridViewRow row = rows[i];
    }
}

好的,我知道了错误,但是为什么要这样编码呢?“这是一个奇怪的时间想要改变该属性。@LarsTech感谢您的确认。列设置为自动调整大小。但是,dgv允许用户通过在两个列标题之间单击并拖动来调整特定列的大小。为了获得更好的响应,行设置为“自动调整大小”“无”,否则在调整列的大小时会变长。因此,上面的代码是一个非常精简的调整列大小逻辑版本。您解决了这个问题吗?我现在遇到了完全相同的问题,我正在努力解决:/@Misiu最终包装了dgv.AutoSizeRowsMode=DataGridViewAutoSizeRowsMode.None;在try-catch@Misiu中,我添加了一个答案来防止异常。在我看来,引发错误的默认行为是一个bug。既然WinForms是开源的,那么这是否应该作为一个bug报告呢?你能填一个描述这个问题的问题吗?
    private void OnRowGlobalAutoSize(int rowIndex)
    {
        DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
//...
    }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization | System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static void LoopThroughRows(DataGridView dgv) {
    DataGridViewRowCollection rows = dgv.Rows;
    for (int i = rows.Count - 1; i >= 0; i--) {
        DataGridViewRow row = rows[i];
    }
}