更改单元格的BackColor无法在Form的构造函数

时间:2016-09-14 17:20:49

标签: c# .net winforms data-binding datagridview

我的代码看起来非常简单,我不确定我错过了什么......

我循环遍历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属性,但我没有得到任何结果......

2 个答案:

答案 0 :(得分:2)

您在构造函数中的DataGridView的单元格和行(在形式Load事件之前)中所做的更改将不会保留,并且它们将丢失。它不仅仅是样式,而是行和单元格的所有变化。

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

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

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

答案是因为OnBindingContextChanged的{​​{1}}。

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

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

OnBindingContextChanged

因此,加载后看到的列和行不是您在构造函数中看到的那些。它们是新物体。因此,您在构造函数中对行和列所做的更改将不会保留。

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

虽然您可以将代码移至private void RefreshColumnsAndRows() { this.Rows.ClearInternal(false /*recreateNewRow*/); RefreshColumns(); RefreshRows(true /*scrollIntoView*/); } Load事件,但动态设置行和单元格的更合适的位置是使用Form事件DtaGridView

答案 1 :(得分:0)

装饰细胞不会粘上&#34;当您尝试在窗体的构造函数中运行代码时。将其移至表单的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");
      }
    }
  }
}