fdkgfosfskjdlsjdlkfsf
fdkgfosfskjdlsjdlkfsf

Reputation: 3303

Can DataGridView be used to accomplish the following table-like UI in WinForms?

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:

enter image description 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

Answers (2)

Maciej Los
Maciej Los

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:

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

Reza Aghaei
Reza Aghaei

Reputation: 125207

Yes, you can create such user interface using a DataGridView:

  • You can set RowCount and ColumnCount of grid manually.
  • You can hanlde CellFormatting event of DataGridView and set the value and back color of cell there.
  • You can not use data-binding with current structure of data.

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

Related Questions