Reputation: 3303
It's been a pain in the butt, but I've been using a TableLayoutPanel
to display some data as seen in the below screenshot. But several times it's been suggested that this can be easily done with a DataGridView
.
So my question is, can the following screenshot be accomplished in a Windows Form using a DataGridView
? I've searched the web and nothing similar to what's below.
An answer would be "Yes, it can." or "No, it's not possible.". But please do not post alternatives since the purpose of the question is to finally know if something like this can be accomplished a DataGridView
.
The DataTable
looks like the following:
BG_Color EmpId ColNum RowNum
Yellow 4304 1 1
Yellow 8464 2 1
Yellow 2012 3 1
Blue 4593 1 2
Blue 3515 2 2
Blue 0546 3 2
Green 4346 1 3
Green 5426 2 3
Green 0551 3 3
The result is the following. It's display-only and nothing's clickable here:
How is this possible with a DataGridView
? I've even included where exactly each cell will be, by RowNum
and ColNum
, just in case it's needed.
Or if someone can share a link on something similar, it would be appreciated.
Thanks.
Upvotes: 1
Views: 1217
Reputation: 8591
As i mentioned in the comment to the question, it's quite easy to achieve that, but there's only one condition: the data stored in the datatable have to be pivoted. How? Take a look at example:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//create DataTable
DataTable dt = CreateCustomDataTable();
var pivotDt = dt.AsEnumerable()
.GroupBy(x => x.Field<int>("RowNum"))
.Select(grp => new
{
BG_Color = grp.First().Field<string>("BG_Color").ToLower(), //System.Drawing.Color.FromName(grp.First().Field<string>("BG_Color")),
Emp1 = grp.Where(e => e.Field<int>("ColNum") == 1).Select(a => a.Field<int>("EmpId")).SingleOrDefault(),
Emp2 = grp.Where(e => e.Field<int>("ColNum") == 2).Select(a => a.Field<int>("EmpId")).SingleOrDefault(),
Emp3 = grp.Where(e => e.Field<int>("ColNum") == 3).Select(a => a.Field<int>("EmpId")).SingleOrDefault()
}).ToList();
dataGridView1.DataSource = pivotDt;
dataGridView1.Columns[0].Visible = false;
}
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
e.CellStyle.BackColor = Color.FromName(dgv.Rows[e.RowIndex].Cells[0].Value.ToString());
e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
e.CellStyle.SelectionBackColor = Color.Transparent;
}
//...
}
Result:
For such amount of data the risk of loss of performance is equal to zero.
And final note about your main question:
(...) can the following screenshot be accomplished in a Windows Form using a datagridview?
An answer would be Yes, it can or No, it's not possible. (...)
Yes. it is possible - quite easily.
Upvotes: 1
Reputation: 125207
Yes, you can create such user interface using a DataGridView
:
RowCount
and ColumnCount
of grid manually.CellFormatting
event of DataGridView
and set the value and back color of cell there.Here is a working example with your sample data:
DataTable table;
private void Form1_Load(object sender, EventArgs e)
{
table = GetData();
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.ReadOnly = true;
this.dataGridView1.RowHeadersVisible = false;
this.dataGridView1.ColumnHeadersVisible = false;
this.dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
this.dataGridView1.RowTemplate.Height = 64;
this.dataGridView1.CellFormatting += dataGridView1_CellFormatting;
this.dataGridView1.ColumnCount = (int)table.Compute("Max(ColNum)", "");
this.dataGridView1.RowCount = (int)table.Compute("Max(RowNum)", "");
}
void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.RowIndex >= 0 & e.ColumnIndex >= 0)
{
var row = table.Select(string.Format("RowNum={0} AND ColNum={1}",
e.RowIndex + 1, e.ColumnIndex + 1)).FirstOrDefault();
if (row != null)
{
e.Value = row["EmpId"];
var color = (Color)new ColorConverter().ConvertFrom(row["BG_Color"]);
e.CellStyle.BackColor = color;
e.CellStyle.SelectionBackColor = color;
e.CellStyle.SelectionForeColor = Color.Black;
e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
}
}
}
Upvotes: 2