C#条件格式化动态生成的控件

时间:2018-07-31 12:39:51

标签: c# .net winforms

我尝试根据文件中包含的数据组(settlementPeriod)动态创建选项卡,每个组上都有自己的表格。

然后我添加了创建的表并将它们添加到DataGridViews列表中,以便以后进行操作。

DataGridView dgv = new DataGridView();
tableList.Add(dgv);

foreach (var dgv in tableList)
    for (int l = 0; l < dgv.Rows.Count; l++)

但是,程序将为tableRows(dgv.Rows)返回空集,并且永远不会进入循环。它仅返回未动态生成的DataGridView的数据。 (例如,如果我将dataGridView1添加到tableList中)


我试图遍历选项卡列表(每个选项卡只有一个表),但是也没有成功

foreach(var page in tabList)
    DataGridView dgv = page.Controls.OfType<DataGridView>() as DataGridView;

我在下面包括了所有相关代码。任何帮助表示赞赏。 供参考,“结果”是一类数据。 谢谢//.

private List<DataGridView> tableList = new List<DataGridView>();

private void CreateTables()
{
        var listItemsBySettlementPeriod = results.GroupBy(items => items.settlementPeriod)
                            .Select(group => group.ToList())
                            .ToList();

        for (int i = 0; i < listItemsBySettlementPeriod.Count(); i++)
        {
            tabControl1.TabPages.Add(listItemsBySettlementPeriod[i][0].settlementPeriod);
            tabList.Add(tabControl1.TabPages[(i + 1)]);

            DataGridView dgv = new DataGridView();
            tableList.Add(dgv);
            dgv.Height = 300;    dgv.Width = 1200;

            DataTable dt = new System.Data.DataTable();
            DataRow row;
            string[] header = {"bidType", "date", "unitID", "price", "offerVolume"};

            for (int j = 0; j < listItemsBySettlementPeriod[i].Count(); j++)
            {
                if (j == 0)
                    for (int k = 0; k < header.Count(); k++)
                        dt.Columns.Add(header[k], typeof(string));

                row = dt.NewRow();
                foreach (var value in listItemsBySettlementPeriod[i])
                {
                    row[0] = value.bidType;
                    row[1] = value.acceptTime;
                    row[2] = value.unitID;
                    row[3] = value.price;
                    row[4] = value.volume;
                }
                dt.Rows.Add(row);
            }
            dgv.DataSource = dt;  
            tabControl1.TabPages[(i + 1)].Controls.Add(dgv);
        }

        foreach (var dgv in tableList)
        {
            for (int l = 0; l < dgv.Rows.Count; l++) //CONDITIONAL FORMATING
            {
                string val = "";
                if (dgv.Rows[l].Cells[0].Value != null)
                    val = dgv.Rows[l].Cells[0].Value.ToString();

                if (val == "OFFER")
                    dgv.Rows[l].DefaultCellStyle.BackColor = Color.OrangeRed;
                else if (val == "BID")
                    dgv.Rows[l].DefaultCellStyle.BackColor = Color.CornflowerBlue;
                else
                    dgv.Rows[l].DefaultCellStyle.BackColor = Color.LightGray;
            }
            dgv.Refresh();
        }
}

1 个答案:

答案 0 :(得分:1)

在控件被实际绘制(显示)之前,未对其应用任何数据绑定,等等。

因此,从方法中删除最后一个foreach循环。

使用RowPrePaint事件进行条件格式化。

...
dgv.DataSource = dt;
dgv.RowPrePaint += Dgv_RowPrePaint; // subscribe to event
...

事件处理程序:

private void Dgv_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
    var dgv = (DataGridView)sender;
    var row = dgv.Rows[e.RowIndex];
    var val = row.Cells[0].Value?.ToString();

    if (val == "OFFER")
        row.DefaultCellStyle.BackColor = Color.OrangeRed;
    else if (val == "BID")
        row.DefaultCellStyle.BackColor = Color.CornflowerBlue;
    else
        row.DefaultCellStyle.BackColor = Color.LightGray;
}

此外,请勿使用dgv.Refresh()。我经常在代码中看到如何使用此Refresh方法。在这种情况下,这是没有意义的。