You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中DataGridView操作触发数组索引越界问题求助

DataGridView数组索引越界问题分析与修复

问题场景

你需要给DataGridView的每一行询问测量样本数量,生成对应最大数量的列,并将每行超过自身样本数的列标红,但运行时出现数组索引越界错误。

原代码

nombredemesures = new int[] { };
foreach (DataGridViewRow row in dataGridView2.Rows)
{
    if (row.Cells[$"{comboBox1.Text + comboBox2.Text}DataGridViewTextBoxColumn"].Value?.ToString() is "")
    {
        row.Visible = false;
    }
    else
    {
        string result = Interaction.InputBox($"Valeur de :{row.Cells[\"ItemDataGridViewTextBoxColumn\"].Value?.ToString()}", "Title", "Default Text");
        nombredemesures = nombredemesures.Concat(new int[] { int.Parse(result) }).ToArray();
    }
}
int max = 0;
foreach (int value in nombredemesures)
{
    if (value > max)
        max = value;
}
int k = 0;
for (int i = 1; i <= max; i++) 
{ 
    dataGridView2.Columns.Add($"Test{i}", $"Donée de mesure{i}"); 
}
var resultt = from DataGridViewRow roww in dataGridView2.Rows select roww.Index;
foreach (var i in resultt)
{
    for (int j = max;j>(nombredemesures[k]); j--)
    {
        dataGridView2.Rows[i].Cells[$"Test{j}"].Style.BackColor = System.Drawing.Color.Red;
    }
    k++;
}

错误原因

数组越界的核心问题是数据不匹配:

  • 你仅在行可见且单元格非空时,才往nombredemesures数组中添加元素,但后续遍历的是DataGridView的所有行(包括被设置为Visible=false的行)。
  • 假设总行数为4,其中1行被隐藏,那么nombredemesures的长度是3,但遍历会执行4次,当k=3时,访问nombredemesures[3]就会触发索引越界。

此外还有两个次要问题:

  • 使用数组Concat的方式性能极差,每次添加元素都会创建新数组,建议改用List<T>。
  • int.Parse未做输入验证,用户输入非数字时会直接抛出异常。

修复后的代码

改用列表存储行与样本数的关联,避免索引不匹配的问题,同时增加输入验证:

// 用列表存储可见行和对应的样本数,避免索引不匹配
var rowMeasurements = new List<(DataGridViewRow Row, int MeasurementCount)>();

foreach (DataGridViewRow row in dataGridView2.Rows)
{
    string cellValue = row.Cells[$"{comboBox1.Text + comboBox2.Text}DataGridViewTextBoxColumn"].Value?.ToString();
    if (string.IsNullOrEmpty(cellValue))
    {
        row.Visible = false;
    }
    else
    {
        string input = Interaction.InputBox($"Valeur de :{row.Cells["ItemDataGridViewTextBoxColumn"].Value?.ToString()}", "Title", "Default Text");
        // 验证输入是否为有效数字,避免异常
        if (int.TryParse(input, out int count))
        {
            rowMeasurements.Add((row, count));
        }
        else
        {
            // 输入无效时设置默认值,可根据需求调整
            rowMeasurements.Add((row, 0));
        }
    }
}

// 没有需要处理的行时直接返回
if (rowMeasurements.Count == 0)
    return;

// 简化最大值计算
int maxCount = rowMeasurements.Max(item => item.MeasurementCount);

// 添加测量列
for (int i = 1; i <= maxCount; i++)
{
    dataGridView2.Columns.Add($"Test{i}", $"Donée de mesure{i}");
}

// 遍历关联数据,设置列背景色
foreach (var item in rowMeasurements)
{
    DataGridViewRow row = item.Row;
    int count = item.MeasurementCount;
    for (int j = maxCount; j > count; j--)
    {
        // 额外检查列是否存在,避免列名拼写错误导致的问题
        if (dataGridView2.Columns[$"Test{j}"] != null)
        {
            row.Cells[$"Test{j}"].Style.BackColor = System.Drawing.Color.Red;
        }
    }
}

关键改进点

  1. 使用List<(DataGridViewRow Row, int MeasurementCount)>存储可见行和样本数的关联,确保后续遍历的行都有对应的样本数,不会出现索引越界。
  2. 用int.TryParse替代int.Parse,避免输入非数字时抛出异常。
  3. 简化最大值计算,使用LINQ的Max方法更简洁。
  4. 增加列存在性检查,避免列名拼写错误导致的额外问题。

内容的提问来源于stack exchange,提问作者LiterallyGutsFromBerserk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:47:03