更改单元格的背景色在Form的构造函数中不起作用 [英] Changing the BackColor of a Cell Does't work in Form's Constructor

查看:92
本文介绍了更改单元格的背景色在Form的构造函数中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码看起来很简单,我不确定我缺少什么...



我正在遍历<$ c $中的每一行c> dataGridView.Rows ,然后遍历每个单元格并检查其值是否为 OK ,然后将单元格颜色更改为 Color.Red ,还可以在控制台中写入如果是真的



我在控制台窗口中有一个很好的 IF WAS TRUE 只是向我证明if语句被捕获了。但是我的单元格颜色保持不变,白色



任何建议将不胜感激!

 公共局部类Form1:表单
{
public static BindingList< Record> record_list = new BindingList< Record> {};
public static DataGridViewCellStyle style = new DataGridViewCellStyle();
公共Form1()
{
InitializeComponent();
FillData();
foreach(dataGridView.Rows中的DataGridViewRow行)
{
for(var i = 0; i< row.Cells.Count; i ++)
{
控制台.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 {获取;组; }
公用字串UserName {get;组; }
public int EvtActive {get;组; }
public double EvtTime {get;组; }
公共字符串EvtTimeString {get;组; }
公用字串LocCode {get;组; }
public double LastLoop {get;组; }
public int CompLvl {get;组; }
public int RecordID {get;组; }
public double ConnectTime {get;组; }
公用字串Notes {get;组; }

public Record(字符串a,字符串b,int c,double d,字符串e,
字符串f,double g,int h,int i,double j,字符串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属性,但没有任何结果...

解决方案

您所做的更改构造函数中 DataGridView 的单元格和行(在窗体 Load 事件之前)将不会保留,并且将丢失。这不仅关乎样式,还关乎行和单元格上的所有更改。



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



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



为什么要对 DataGridView



答案是因为 OnBindingContextChanged of DataGridView



当您显示表单显示 Form 的任务序列会导致调用以下方法: CreateControl OnBindingContextChanged 。导致每个子控件的 OnParentBindingContextChanged 被调用,结果,将调用所有子控件的 OnBindingContextChanged 。 / p>

现在,如果您查看 DataGridView.OnBindingContextChanged 您会看到,名为 RefreshColumnsAndRows 调用它将清除所有行和列并再次添加它们:

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

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



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



尽管您可以将代码移至 Form Load 事件,但是使用 DtaGridView


CellFormatting
事件

My code seems pretty straight forward, I'm not sure what I'm missing...

I'm looping through each row in dataGridView.Rows, then looping through each cell and checking if its value is "OK" then I change the cell color to Color.Red and also write "IF WAS TRUE" in console.

I have that nice little "IF WAS TRUE" in console window just to prove to myself that the if statement is getting caught (it is). But my cell color remains unchanged White.

Any advice would be appreciated!

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;
    }
}

EDIT: This was marked as duplicate, but this seems different to me. In the other SO post, it looks like a cell is being sent to a function directly where as I am iterating over cells. I try to call the BackColor property in a similar manner and I get no results...

解决方案

The changes which you make on cells and rows of DataGridView in constructor (before form Load event) will not be persisted and they will be lost. It's not about just styles, it's about all changes on rows and cells.

In fact the columns and rows which you see after load are not those that you see in constructor.

The short answer (as said) is you should initialize styles in Load event of form. But Why?

Why do changes which you make on cells and rows of DataGridView in constructor don't persist and they lost?

The answer is because of OnBindingContextChangedof DataGridView.

When you show a Form sequence of tasks that shows a Form cause calling these methods: CreateControlOnBindingContextChanged. Which cause OnParentBindingContextChanged of each child control be called and as a result, OnBindingContextChanged of all child controls will be called.

Now if you take a look at DataGridView.OnBindingContextChanged you will see, a method named RefreshColumnsAndRows called which clears all rows and columns and add them again:

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

So the columns and rows which you see after load are not those that you see in constructor. They are new objects. So changes which you made on rows and columns in constructor will not be persisted.

What's the correct way of dynamically changing styles?

Although you can move your code to Load event of Form but a more suitable place to style rows and cells dynamically is using CellFormatting event of DtaGridView

这篇关于更改单元格的背景色在Form的构造函数中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆