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

DataGridView排序时同行列非目标列单元格背景色被重置的问题求助

DataGridView排序时同行列非目标列单元格背景色被重置的问题求助

大家好,我碰到了一个DataGridView的棘手问题,想请各位帮忙看看:

背景情况

我有一个DataGridView,当用户对某一列进行排序时,会触发dataGridView1_Sorted事件,在这个事件里我会给目标列中值发生变化的下一个单元格设置不同的背景色。

遇到的问题

当我先对列1排序并成功给列1的单元格设置好颜色后,再对列2进行排序时,列1的着色会被重置回默认样式(背景色消失了)。
如果我放慢操作,只修改列2的少数行,那么只有这些被修改过的行,它们的列1背景色会被重置。

触发排序的事件代码如下:

private void dataGridView1_Sorted(object sender, EventArgs e)
{
    DataGridView dgv = (DataGridView)sender;
    ColorCodeWaferDataGridView(ref dgv);
}

我尝试过的方法

最开始我是通过创建新的单元格样式来设置颜色的,代码大概是这样:

DataGridView dataGridView1 = dgv; //为了简化代码
// 创建新样式
DataGridViewCellStyle changedStyle = new DataGridViewCellStyle();
changedStyle.BackColor = Color.Aqua;
changedStyle.ForeColor = Color.Black;
changedStyle.Font = dgv.DefaultCellStyle.Font;
// 给指定行的单元格设置样式
int row = 1;
string sortedColName = "MyColumn1";
dgv.Rows[row].Cells[sortedColName].Style = changedStyle;

后来我试着只单独设置背景色,担心是默认格式的问题,改成了这样:

dgv.Rows[row].Cells[sortedColName].Style.BackColor = changedStyle.BackColor;

另外我知道DataGridViewCellStyle需要用.Clone()来复制,因为直接赋值只是引用同一个实例,比如:

错误的写法:
DataGridViewCellStyle changedStyle_doesntwork = originalStyle;
正确的写法:
DataGridViewCellStyle myNewStyle = originalStyle.Clone();

现在我的完整代码大概是这样的:

触发事件的方法

private void dataGridView1_Sorted(object sender, EventArgs e)
{
    DataGridView dgv = (DataGridView)sender;
    ColorCodeDataGridView(ref dgv);
}

着色的核心方法

private void ColorCodeDataGridView(ref DataGridView dgv)
{
    string sortedColName = dgv.SortedColumn.Name.ToString();
    // 创建初始着色样式
    DataGridViewCellStyle changedStyle = new DataGridViewCellStyle();
    changedStyle.BackColor = Color.Aqua;
    changedStyle.ForeColor = Color.Black;
    changedStyle.Font = dgv.DefaultCellStyle.Font;
    //changedStyle.Font = new Font(changedStyle.Font.FontFamily, changedStyle.Font.Size, FontStyle.Bold);

    // 处理第一行的特殊情况
    dgv.Rows[0].Cells[sortedColName].Style = changedStyle;

    for (int row = 1; row < dgv.RowCount; row++)
    {
        // 如果当前行的值和上一行不同,切换颜色
        if (dgv.Rows[row].Cells[sortedColName].Value.ToString()
        != dgv.Rows[row - 1].Cells[sortedColName].Value.ToString())
        {
            changedStyle = NewChangedStyle2(changedStyle);
            dgv.Rows[row].Cells[sortedColName].Style.BackColor = changedStyle.BackColor;
            dgv.Rows[row].Cells[sortedColName].Style.ForeColor = changedStyle.ForeColor;
        }
        else
        {
            dgv.Rows[row].Cells[sortedColName].Style.BackColor = changedStyle.BackColor;
        }
    }
    dgv.ClearSelection(); // 避免第一单元格默认选中呈蓝色
}

切换颜色的辅助方法

// 获取已知颜色列表中的下一个颜色
private static DataGridViewCellStyle NewChangedStyle2(DataGridViewCellStyle originalStyle)
{
    // 获取当前背景色对应的已知颜色枚举值
    int k = (int)originalStyle.BackColor.ToKnownColor();
    DataGridViewCellStyle myNewStyle = originalStyle.Clone();
    myNewStyle.BackColor = Color.FromKnownColor((KnownColor)(k + 1));

    // 根据背景色亮度调整文字颜色,保证可读性
    float f = myNewStyle.BackColor.GetBrightness();
    if (f < 0.5)// 深色背景用白色文字
    {
        myNewStyle.ForeColor = Color.White;
    }
    else // 浅色背景用黑色文字
    {
        myNewStyle.ForeColor = Color.Black;
    }
    return myNewStyle;
}

现在就是不知道为什么排序其他列时,之前设置好颜色的列会被重置,有没有大佬能指点一下问题出在哪?

备注:内容来源于stack exchange,提问作者AApperson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 10:27:59