C# DataGridViewComboBoxColumn 索引超出设计器文件中设置 HeaderText 的范围

问题描述 投票:0回答:1

我的表单上有一个 DataGridView,其中有一个 ComboBox 列。

当表单加载时,网格没有数据源,因为它是通过用户触发的另一种方法加载到网格的。

加载表单时(创建表单实例),我收到错误:

索引超出范围。必须为非负数且小于集合的大小。

当为列设置标题文本时,我已将其范围缩小到表单设计器文件中的行。这是导致 Form1.Designer.cs 文件中出现错误的代码行:

this.gridComboBox1.HeaderText = "Options";

如果我注释掉这一行,表单加载不会出现问题,但网格中组合框列的标题只是“gridComboBox1”,这显然不理想。

我正在使用 Visual Studio 创建表单,因此尝试从工具箱向应用程序添加一个全新的 datagridview 控件并设置列,而不更改除设置列类型和标题文本之外的任何设置。但我遇到了同样的问题,这让我认为这是 winforms 的一个问题,因为它提供了不起作用的功能。

如果我尝试以编程方式更改表单的加载事件中的标题文本,也会遇到相同的错误。

我对 C# 还很陌生,一直无法弄清楚为什么会发生这种情况。该列本身是在设计器文件的代码中较早添加的,如下所示:

this.dgv1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.select,
            this.gridComboBox1,
            this.DataType});

所以该列应该供后面的代码交互。

有人能够解释为什么会这样吗,因为这对我来说毫无意义。

c# datagridview datagridviewcomboboxcolumn
1个回答
0
投票

我现在做了更多调查,我相信我已经解决了这个问题。

我订阅 CellValueChanged 事件以触发一些代码,这些代码根据从 ComboBox 列中选择的选项填充网格中的另一列。

但是,当设计器代码设置标题文本时,会触发此事件。

这是有问题的代码:

private void dgv1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    try
    {
        if (e.ColumnIndex == 1) // index of the combobox column
        {
            string mappedField = dgv1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
            string sql = @$"SELECT 
                            UPPER(DATA_TYPE) 
                            + CASE 
                                WHEN DATA_TYPE IN ('nvarchar', 'varchar') AND CHARACTER_MAXIMUM_LENGTH = -1 THEN '(MAX)' 
                                WHEN DATA_TYPE IN ('nvarchar', 'varchar') THEN '('+CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) + ')' 
                                ELSE '' 
                                END AS DATA_TYPE 
                        FROM INFORMATION_SCHEMA.COLUMNS 
                        WHERE TABLE_NAME = 'Report'
                        AND COLUMN_NAME = '{mappedField}';";
            string targetDataType = clsRepeatableMethods.SQLOutputToStringVariable(sql, clsConnections.ConnStrStg);

            dgv1.Rows[e.RowIndex].Cells["RepDataType"].Value = targetDataType;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

由于设计者创建网格时网格中除标题行外没有任何行,因此返回索引超出范围错误。

修复方法是同时检查行索引。

我更改了这行代码:

if (e.ColumnIndex == 1)

对此:

if (e.RowIndex != -1 && e.ColumnIndex == 1)

现在一切正常了。

感谢@Sinatr,他的评论让我进一步了解可以触发哪些其他代码。

© www.soinside.com 2019 - 2024. All rights reserved.