在Form's构造函数中更改单元格的背景色不起作用

本文关键字:单元格 不起作用 背景色 构造函数 Form | 更新日期: 2023-09-27 18:06:57

我的代码看起来很直接,我不确定我错过了什么…

我循环遍历dataGridView.Rows中的每一行,然后循环遍历每个单元格并检查其值是否为"OK",然后我将单元格颜色更改为Color.Red,并在控制台中写入"IF WAS TRUE"

我在控制台窗口中有一个漂亮的小"IF WAS TRUE",只是为了向自己证明if语句正在被捕获(它是)。但我的细胞颜色保持不变White

任何建议将不胜感激!

public partial class Form1 : Form
{
    public static BindingList<Record> record_list = new BindingList<Record> { };
    public static DataGridViewCellStyle style = new DataGridViewCellStyle();
    public Form1()
    {
        InitializeComponent();
        FillData();
        foreach (DataGridViewRow row in dataGridView.Rows)
        {
            for (var i = 0; i < row.Cells.Count; i++)
            {
                Console.WriteLine(row.Cells[i].Value);
                if (row.Cells[i].Value as string == "OK")
                {
                    row.Cells[i].Style.BackColor = Color.Red;
                    Console.WriteLine("IF WAS TRUE");
                }
            }
        }
    }
    void FillData()
    {
        record_list.Add(new Record("Support-19", "TEST", 0, 0.0, "", 
            "LOC CODE2", 0.0, 0, 0, 0.0, ""));
        record_list.Add(new Record("Support-99", "ROBOTS", 0, 0.0, "",
            "OK", 0.0, 0, 0, 0.0, ""));
        record_list.Add(new Record("Support-27", "TEST2", 0, 0.0, "", 
            "LOC CODE1", 0.0, 0, 0, 0.0, ""));
        dataGridView.DataSource = record_list;
    }
}
public class Record
{
    public string Station { get; set; }
    public string UserName { get; set; }
    public int EvtActive { get; set; }
    public double EvtTime { get; set; }
    public string EvtTimeString { get; set; }
    public string LocCode { get; set; }
    public double LastLoop { get; set; }
    public int CompLvl { get; set; }
    public int RecordID { get; set; }
    public double ConnectTime { get; set; }
    public string Notes { get; set; }
    public Record(string a, string b, int c, double d, string e,
        string f, double g, int h, int i, double j, string k)
    {
        this.Station = a;
        this.UserName = b;
        this.EvtActive = c;
        this.EvtTime = d;
        this.EvtTimeString = e;
        this.LocCode = f;
        this.LastLoop = g;
        this.CompLvl = h;
        this.RecordID = i;
        this.ConnectTime = j;
        this.Notes = k;
    }
}
编辑:这被标记为重复,但这对我来说似乎不同。在另一个SO帖子中,它看起来像一个单元格被直接发送到一个函数,因为我在单元格上迭代。我尝试以类似的方式调用BackColor属性,我没有得到任何结果…

在Form's构造函数中更改单元格的背景色不起作用

在构造函数中(在表单Load事件之前)对DataGridView的单元格和行所做的更改将不会被持久保存,并且它们将丢失。这不仅仅是关于样式,而是关于行和单元格的所有更改。

实际上,你在加载后看到的列和行并不是你在构造函数中看到的。

简短的回答(如前所述)是你应该初始化样式的Load事件的形式。但是为什么呢?

为什么在构造函数中对DataGridView的单元格和行进行的更改不会持续存在并且会丢失?

答案是因为DataGridViewOnBindingContextChanged

当您显示Form任务序列时,显示Form原因调用这些方法:CreateControlOnBindingContextChanged。这将导致每个子控件的OnParentBindingContextChanged被调用,因此,所有子控件的OnBindingContextChanged将被调用。

现在,如果你看一下DataGridView.OnBindingContextChanged,你会看到,一个名为RefreshColumnsAndRows的方法被调用,它清除所有的行和列,并再次添加它们:

private void RefreshColumnsAndRows()
{
    this.Rows.ClearInternal(false /*recreateNewRow*/);
    RefreshColumns();
    RefreshRows(true /*scrollIntoView*/);
}

所以你在加载后看到的列和行不是你在构造函数中看到的。它们是新的对象。因此,您对构造函数中的行和列所做的更改将不会被持久化。

动态改变样式的正确方法是什么?

虽然你可以将你的代码移动到FormLoad事件,但一个更合适的地方来动态地样式行和单元格是使用DtaGridViewCellFormatting事件

当您尝试在表单的构造函数中运行代码时,装饰单元格不会"粘附"。把它移到表单的OnLoad重载中:

protected override void OnLoad(EventArgs e) {
  base.OnLoad(e);
  foreach (DataGridViewRow row in dataGridView.Rows)
  {
    for (var i = 0; i < row.Cells.Count; i++)
    {
      Console.WriteLine(row.Cells[i].Value);
      if (row.Cells[i].Value as string == "OK")
      {
        row.Cells[i].Style.BackColor = Color.Red;
        Console.WriteLine("IF WAS TRUE");
      }
    }
  }
}