Reputation: 54
I've attempted to dynamically create tabs depending on how many groups of data I have in a file (settlementPeriod), each with their own table on them.
I've then added the created tables and added them to a List of DataGridViews, in order to manipulate them later.
DataGridView dgv = new DataGridView();
tableList.Add(dgv);
foreach (var dgv in tableList)
for (int l = 0; l < dgv.Rows.Count; l++)
However, the program returns a null set for the tableRows (dgv.Rows) and never enters the loop. It only returns data for DataGridViews that are not dyanamically generated. (For example if I addded dataGridView1 to the tableList)
I've attempted to iterate through the list of tabs (as there's only one table per tab), but to no success either
foreach(var page in tabList)
DataGridView dgv = page.Controls.OfType<DataGridView>() as DataGridView;
I've included all relevant code below. Any help is appreciated. For reference "results" is a class of data. Thanks//.
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();
}
}
Upvotes: 1
Views: 69
Reputation: 14231
Until the control is actually drawn (shown), no data binding is applied to it, etc.
So remove the last foreach loop from your method.
Do conditional formatting with the RowPrePaint
event.
...
dgv.DataSource = dt;
dgv.RowPrePaint += Dgv_RowPrePaint; // subscribe to event
...
Event handler:
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;
}
Also, do not use dgv.Refresh()
. Very often I see in the code how this Refresh
method is used for nothing. It is meaningless in this context.
Upvotes: 1