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

WinForms中ComboBox切换后DataGridView单元格格式失效求助

WinForms DataGridView 格式失效问题

首次选择ComboBox中的选项时,DataGridView的单元格格式可正常应用;但后续再次选择选项时,格式不再生效,单元格变为空白。

相关代码

int t = 0;
foreach (DataGridViewRow row in dataGridView2.Rows)
{
    row.Cells["toleranceMinDataGridViewTextBoxColumn"].Value = "";
    row.Cells["toleranceNomDataGridViewTextBoxColumn"].Value = "";
    row.Cells["toleranceMaxDataGridViewTextBoxColumn"].Value = "";

    row.Cells["toleranceMinDataGridViewTextBoxColumn"].ReadOnly = false;
    row.Cells["toleranceNomDataGridViewTextBoxColumn"].ReadOnly = false;
    row.Cells["toleranceMaxDataGridViewTextBoxColumn"].ReadOnly = false;

}

void creation()
{
    dataGridView2.Columns.OfType<DataGridViewColumn>().ToList().ForEach(col => col.Visible = false);
    dataGridView2.Columns["lotDataGridViewTextBoxColumn"].Visible = true;
    dataGridView2.Columns["ItemDataGridViewTextBoxColumn"].Visible = true;
    dataGridView2.Columns["lotDataGridViewTextBoxColumn"].Visible = true;
    dataGridView2.Columns["ItemDataGridViewTextBoxColumn"].Visible = true;
    dataGridView2.Columns["toleranceMinDataGridViewTextBoxColumn"].Visible = true;
    dataGridView2.Columns["toleranceNomDataGridViewTextBoxColumn"].Visible = true;
    dataGridView2.Columns["toleranceMaxDataGridViewTextBoxColumn"].Visible = true;


    dataGridView2.Columns[$"toleranceMinDataGridViewTextBoxColumn"].DefaultCellStyle.BackColor = System.Drawing.Color.Wheat;
    dataGridView2.Columns[$"toleranceNomDataGridViewTextBoxColumn"].DefaultCellStyle.BackColor = System.Drawing.Color.Wheat;
    dataGridView2.Columns[$"toleranceMaxDataGridViewTextBoxColumn"].DefaultCellStyle.BackColor = System.Drawing.Color.Wheat;
}

creation();


void creationitemsettolerances()
{
    foreach (DataGridViewRow row in dataGridView2.Rows)
    {
        row.Visible = false;
    }

    foreach (DataGridViewRow row in dataGridView2.Rows)
    {
        if (!(row.Cells[$"{comboBox1.Text + comboBox2.Text}DataGridViewTextBoxColumn"].Value?.ToString() is ""))
        {
            row.Visible = true;;
        }

    }

    var result = from DataGridViewRow row in dataGridView2.Rows where row.Visible select row;


    foreach (DataGridViewRow row in result)
    {
        string[] splitter = new string[3];
        t++;
        string a = row.Cells[$"{comboBox1.Text + comboBox2.Text}DataGridViewTextBoxColumn"].Value?.ToString();
        if (a.Contains('-'))
        {
            splitter = a.Split('-');
            row.Cells["toleranceMinDataGridViewTextBoxColumn"].Value = splitter[0];
            row.Cells["toleranceNomDataGridViewTextBoxColumn"].Value = splitter[1];
            try {
                row.Cells["toleranceMaxDataGridViewTextBoxColumn"].Value = splitter[2];
            }catch(Exception ex) { Debug.WriteLine(ex); }


        }
        else
        {
            row.Cells["toleranceNomDataGridViewTextBoxColumn"].Value = a;

        }
    }
}

creationitemsettolerances();


void formattagedestolerances()
{
    var result = from DataGridViewRow row in dataGridView2.Rows where row.Visible select row;
    foreach (var row in result)
    {
        if ((row.Cells["toleranceMinDataGridViewTextBoxColumn"].Value?.ToString() is "") && (row.Cells["toleranceMaxDataGridViewTextBoxColumn"].Value?.ToString() is ""))
        {
            string a = row.Cells["toleranceNomDataGridViewTextBoxColumn"].Value?.ToString();
            var cell = (DataGridViewTextBoxCellEx)row.Cells["toleranceMinDataGridViewTextBoxColumn"];
            cell.Value = a;
            cell.ColumnSpan = 3;
            cell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
        }


    }
}
formattagedestolerances();



void definitiondeslots()
{
    int deb1 = 0;
    int deb2 = 0;
    int fin1 = 0;
    int fin2 = 0;
    int deb3 = 0;
    int fin3 = 0;



    var result = from DataGridViewRow row in dataGridView2.Rows where row.Visible select row;

    fin3 = result.Count() ;


    foreach (var row in result)
    {
        if (row.Cells["TolerancesDataGridViewTextBoxColumn"].Value?.ToString() is "1")
        {
             
             if ((row.Cells["lotDataGridViewTextBoxColumn"].Value?.ToString() is "2") && (deb2 == 0))
            {
                deb2 = row.Index;
                fin1 = row.Index - 1;
            }
            else if ((row.Cells["lotDataGridViewTextBoxColumn"].Value?.ToString() is "3") && (deb3 == 0))
            {
                fin2 = row.Index - 1;
                deb3 = row.Index;
            }

        }
        else if(row.Cells["TolerancesDataGridViewTextBoxColumn"].Value?.ToString() is "2")
        {
            if ((row.Cells["lotDataGridViewTextBoxColumn"].Value?.ToString() is "1") && (deb1 == 0))
            {
                deb1 = row.Index;
            }
            else if ((row.Cells["lotDataGridViewTextBoxColumn"].Value?.ToString() is "2") && (deb2 == 0))
            {
                deb2 = row.Index;
                fin1 = row.Index - 1;
            }
            else if ((row.Cells["lotDataGridViewTextBoxColumn"].Value?.ToString() is "3") && (deb3 == 0))
            {
                fin2 = row.Index - 1;
                deb3 = row.Index;
            }
        }
        else if (row.Cells["TolerancesDataGridViewTextBoxColumn"].Value?.ToString() is "3")
        {
            if ((row.Cells["lotDataGridViewTextBoxColumn"].Value?.ToString() is "1") && (deb1 == 0))
            {
                deb1 = row.Index;
            }
            else if ((row.Cells["lotDataGridViewTextBoxColumn"].Value?.ToString() is "2") && (deb2 == 0))
            {
                deb2 = row.Index;
                fin1 = row.Index - 1;
            }
            else if ((row.Cells["lotDataGridViewTextBoxColumn"].Value?.ToString() is "3") && (deb3 == 0))
            {
                fin2 = row.Index - 1;
                deb3 = row.Index;
            }
        }
    }

    var cell1 = (DataGridViewTextBoxCellEx)dataGridView2.Rows[deb1].Cells["lotDataGridViewTextBoxColumn"];
    cell1.RowSpan = fin1 - deb1+1;
    var cell2 = (DataGridViewTextBoxCellEx)dataGridView2.Rows[deb2].Cells["lotDataGridViewTextBoxColumn"];
    cell2.RowSpan = fin2 - deb2+1;
    var cell3 = (DataGridViewTextBoxCellEx)dataGridView2.Rows[deb3].Cells["lotDataGridViewTextBoxColumn"];
    cell3.RowSpan = fin3 -deb3+2;

}


definitiondeslots();

void donneesdemesures()
{
    listBox1.Items.Clear();

    List<int> valeurs = new List<int>();
    var result = from DataGridViewRow row in dataGridView2.Rows where row.Visible select row;
    foreach (var row in result)
    {
        string a = row.Cells[$"donnees{comboBox1.Text + comboBox2.Text}DataGridViewTextBoxColumn"].Value?.ToString();
        if (!(a is ""))
        {
            valeurs.Add(Convert.ToInt32(a));
        }
        listBox1.Items.Add(a);

    }
    int b = valeurs.Max();

    for (int i = 1; i <= b; i++)
    {
        dataGridView2.Columns.Add($"Test{i}", "Donnee");

    }


    foreach (var row in result)
    {
        for (int i = 1; i <= b; i++)
        {
            row.Cells[$"Test{i}"] = new DataGridViewTextBoxCellEx();
        }
    }
    int m = 0;
    foreach (var row in result)
    {
        for (int i = 1; i <= b; i++)
        {
            row.Cells[$"Test{i}"].Style.BackColor = System.Drawing.Color.Gray;
        }

        for (int i = 1; i <= valeurs[m]; i++)
        {
            row.Cells[$"Test{i}"].Style.BackColor = System.Drawing.Color.White;

        }
        m++;

    }

}
donneesdemesures();

问题排查与修复方案

核心问题点

  1. 单元格合并状态未重置:二次选择时,之前设置的ColumnSpan/RowSpan残留,导致单元格布局混乱
  2. 动态列重复添加:每次执行donneesdemesures()都会新增Test系列列,列数量不断累积破坏布局
  3. 自定义单元格状态残留:DataGridViewTextBoxCellEx的合并属性未在每次操作前初始化
  4. 索引越界风险:definitiondeslots()中未判断deb1/deb2/deb3的有效性,可能引发空引用异常

具体修复步骤

1. 重置单元格合并与样式

在每次操作开始时,遍历所有单元格清除之前的合并状态和自定义样式:

foreach (DataGridViewRow row in dataGridView2.Rows)
{
    foreach (DataGridViewCell cell in row.Cells)
    {
        cell.ColumnSpan = 1;
        cell.RowSpan = 1;
        cell.Style = new DataGridViewCellStyle(); // 重置为默认样式
    }
    // 原有的清空值和ReadOnly设置...
}

2. 清理重复动态列

在donneesdemesures()开头移除之前添加的Test列,避免重复添加:

void donneesdemesures()
{
    // 先删除历史Test列
    for (int i = dataGridView2.Columns.Count - 1; i >= 0; i--)
    {
        if (dataGridView2.Columns[i].Name.StartsWith("Test"))
        {
            dataGridView2.Columns.RemoveAt(i);
        }
    }
    // 原有的listBox清空等逻辑...
}

3. 修复单元格合并逻辑

在formattagedestolerances()中确保单元格类型正确,并处理显示状态:

void formattagedestolerances()
{
    var result = from DataGridViewRow row in dataGridView2.Rows where row.Visible select row;
    foreach (var row in result)
    {
        bool minEmpty = string.IsNullOrEmpty(row.Cells["toleranceMinDataGridViewTextBoxColumn"].Value?.ToString());
        bool maxEmpty = string.IsNullOrEmpty(row.Cells["toleranceMaxDataGridViewTextBoxColumn"].Value?.ToString());
        
        if (minEmpty && maxEmpty)
        {
            string a = row.Cells["toleranceNomDataGridViewTextBoxColumn"].Value?.ToString();
            var minCell = row.Cells["toleranceMinDataGridViewTextBoxColumn"];
            
            // 确保是自定义单元格类型
            if (!(minCell is DataGridViewTextBoxCellEx))
            {
                minCell = new DataGridViewTextBoxCellEx();
                row.Cells["toleranceMinDataGridViewTextBoxColumn"] = minCell;
            }
            
            ((DataGridViewTextBoxCellEx)minCell).Value = a;
            ((DataGridViewTextBoxCellEx)minCell).ColumnSpan = 3;
            ((DataGridViewTextBoxCellEx)minCell).Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            
            // 隐藏另外两个单元格避免重叠
            row.Cells["toleranceNomDataGridViewTextBoxColumn"].Visible = false;
            row.Cells["toleranceMaxDataGridViewTextBoxColumn"].Visible = false;
        }
        else
        {
            // 恢复三个单元格的显示
            row.Cells["toleranceNomDataGridViewTextBoxColumn"].Visible = true;
            row.Cells["toleranceMaxDataGridViewTextBoxColumn"].Visible = true;
        }
    }
}

4. 避免索引越界

在definitiondeslots()中添加有效性判断,防止空引用:

void definitiondeslots()
{
    // 原有的变量初始化和遍历逻辑...

    // 添加索引有效性判断
    if (deb1 >= 0 && deb1 < dataGridView2.Rows.Count && fin1 >= deb1)
    {
        var cell1 = (DataGridViewTextBoxCellEx)dataGridView2.Rows[deb1].Cells["lotDataGridViewTextBoxColumn"];
        cell1.RowSpan = fin1 - deb1 + 1;
    }
    if (deb2 >= 0 && deb2 < dataGridView2.Rows.Count && fin2 >= deb2)
    {
        var cell2 = (DataGridViewTextBoxCellEx)dataGridView2.Rows[deb2].Cells["lotDataGridViewTextBoxColumn"];
        cell2.RowSpan = fin2 - deb2 + 1;
    }
    if (deb3 >= 0 && deb3 < dataGridView2.Rows.Count && fin3 >= deb3)
    {
        var cell3 = (DataGridViewTextBoxCellEx)dataGridView2.Rows[deb3].Cells["lotDataGridViewTextBoxColumn"];
        cell3.RowSpan = fin3 - deb3 + 2;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 01:28:05