6

I need to write a function which will set the color in TableLayoutPanel cells depending on some condition during running the program.

TableLayoutPanel is divided by 16x16. There is some condition at the start of the program. If the condition is true for a cell this sell must be painted blue color. For example:

private void start_Click(object sender, EventArgs e)
{
    foreach (string str in some_list)
    {
       if (some condition)
       {
           set_color_in_cell at row[i] colum[j] //(what shoud i use here?)
       }
    }
}

I found such example:

private void tableLayoutPanel_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
    if (e.Row == 0 && e.Column == 1)
    {
        e.Graphics.FillRectangle(new SolidBrush(Color.Black), e.CellBounds);
    }
}

But I don't understand how to use it. If somebody knows about this please help me.

private void start_Click(object sender, EventArgs e)
{
    string SyncAnswer = "";
    foreach (string file_string in Data_from_file)
    {
       COM_Port.WriteLine(file_string);
       while (SyncAnswer != "READY")
       {
           SyncAnswer = COM_Port.ReadLine();
           if (SyncAnswer.Substring(0, 4) == "Fire")
           {
              //raise event
              //paint for example a cell in Row=i Colum=j
           }
           else if (SyncAnswer.Substring(0, 4) == "Skip")
          {
             //raise event
          }
      }
   }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Sergey
  • 103
  • 1
  • 2
  • 9
  • Assign `tableLayoutPanel_CellPaint` to `CellPaint` event of your `tableLayoutPanel` and then paint based on some criteria. `e.Row` is the row index, `e.Column` is column index of the cell. `e.CellBounds` is bound of the cell. – Reza Aghaei Dec 03 '15 at 11:23
  • Unfortunately I'm not good at programming. Could you please clarify what exactly do you mean by adding an example? – Sergey Dec 04 '15 at 06:56
  • You can use CellPaint event or you can simply put panels in cells and change the BackColor of panels. See the answer below. – Reza Aghaei Dec 05 '15 at 06:19

2 Answers2

31

Option 1 - Using CellPaint Event

Here is a step by step example:

  1. Create a Form
  2. Put a TableLayoutPanel from toolbox on your Form
  3. Select tableLayoutPanel1 on design surface and Press F4 Key to see properties.
  4. From toolbar of property grid, you can select to show Properties enter image description here or Events enter image description here. Click on events icon and from the list, double click on CellPaint event to create tableLayoutPanel1_CellPaint event handler in code.
  5. You can paint each cells background in this method based on some criteria. The event will raise for painting each cells background and e.Row is the row index, e.Column is column index and e.CellBounds is bound of the painting cell.

For example in below sample, we draw black background if ((e.Column + e.Row) % 2 == 1) otherwise, we draw white background:

private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
    if ((e.Column + e.Row) % 2 == 1)
        e.Graphics.FillRectangle(Brushes.Black, e.CellBounds);
    else
        e.Graphics.FillRectangle(Brushes.White, e.CellBounds);
}

enter image description here

To change Color Dynamically

To change the color from another point of program, for example in a Click event of a button, you should store back colors of each cell in an 2-dimension array and use that color to create a brush for that cell:

Define bgColors in your form:

Color[,] bgColors = new Color[2, 2] {
    { SystemColors.Control, SystemColors.Control }, 
    { SystemColors.Control, SystemColors.Control } 
};

Draw background of cells this way:

private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
    using (var b = new SolidBrush(bgColors[e.Column, e.Row]))
    {
        e.Graphics.FillRectangle(b , e.CellBounds);
    }
}

To change the BackColor of a Cell you can:

private void Button1_Click(object sender, EventArgs e)
{
    //column: 0 ,row: 1
    bgColors[0, 1] = Color.Red;
    tableLayoutPanel1.Refresh();
}

Option 2 - Hosting Panel in Cells

As another simple option, you can put Panel in each cell, and set the Dock property of Panel to Fill and set its Margin property to 0,0, then each time you want to change color of a panel at position (column, row) you can use this code:

this.tableLayoutPanel1.GetControlFromPosition(column, row).BackColor = Color.Red;
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Ok. Thanks so much. But the point is that this event raise up only at the start of the program. I have to do such way at which the event will raise up only when it is needed over and over again. – Sergey Dec 05 '15 at 03:39
  • I added a piece of code from my program to clarify what i mean – Sergey Dec 05 '15 at 03:46
  • No, the event raises when the `TableLayoutPanel` needs painting (for example after restoring window, or after another form move above it or after you manually call `tableLayoutPanel1.Refresh() or .Invalidate()` – Reza Aghaei Dec 05 '15 at 05:47
  • 1
    As another simple option, you can put `Panel` in each cell, and set the `Dock` property of `Panel` to `Fill` and set its `Margin` property to `0,0`, then each time you want to change color of a panel at position `(column, row)` you can use this code: `this.tableLayoutPanel1.GetControlFromPosition(column, row).BackColor = Color.Red;` – Reza Aghaei Dec 05 '15 at 05:51
  • No problem) it's not difficult for me – Sergey Dec 07 '15 at 06:30
  • Thank you for your feedback :) – Reza Aghaei Dec 07 '15 at 06:30
0

Another way that is pretty simple is to dynamically add multiple PictureBox controls (ex: pbCellColor below) to you cells in your TableLayoutPanel, or some other more simple simple control, dock it, set the margin to zero, then whenever you want:

pbCellColor.Dock = DockStyle.None;
pbCellColor.Margin = new Size(0, 0, 0, 0);
pbCellColor.Backcolor = Color.Red;    

TableLayoutPanel with PictureBox to color cell

Easy, no event handling or state checks. Just set it and forget it. Worst case, if you call from a non-gui thread, you will need to Invoke the action.

Alex Martin
  • 156
  • 9