0

I am very new to Windows Forms, have been searching for an answer for three days already but no luck.

I have a button and a table with multiple cells. enter image description here

When the button is clicked, I need to change the color of the top left cell (index [0, 0]), but I don't understand how to do it since the button's on-click event method doesn't have TableLayoutCellPaintEventArgs element type parameter.

Please advise how to do it.

Jackdaw
  • 7,626
  • 5
  • 15
  • 33
  • Does this answer your question? [How to set cell color in TableLayoutPanel dynamically?](https://stackoverflow.com/questions/34064499/how-to-set-cell-color-in-tablelayoutpanel-dynamically) – Jackdaw Nov 10 '20 at 12:24
  • You need to show how you paint cells right now. From button click event handler you have to communicate to painting code somehow: set some variable to a certain value and force repaint, check for that variable in painting code to alter color. – Sinatr Nov 10 '20 at 12:27

2 Answers2

0

The table cell redrawn event can be used to change cells color at the run-time.

The example below is creating color array to saving color for each cell in the table and using the cell redrawn event to draw it.

Each click on the button change color of the randomly selected cell.

Form1.cs

namespace WindowsFormsTable
{
    public partial class Form1 : Form
    {
        private Color[,] cellColors = null;
        private Random rnd = new Random();

        public Form1()
        {
            InitializeComponent();    

            // Prepare random colors for table cells
            var columns = tableLayoutPanel1.ColumnCount;
            var rows = tableLayoutPanel1.RowCount;                
            cellColors = new Color[columns, rows];

            for (int c = 0; c < columns; c++)
            {
                for (int r = 0; r < rows; r++)
                {
                    // Get random color
                    cellColors[c, r] = GetRandomColor();
                }
            }
        }
        // Table cell is redrawn event handler
        private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
        {
            if (cellColors != null)
            {
                var color = cellColors[e.Column, e.Row];
                e.Graphics.FillRectangle(new SolidBrush(color), e.CellBounds);
            }          
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Change color for randow cell
            var column = rnd.Next(0, tableLayoutPanel1.ColumnCount - 1);
            var row = rnd.Next (0, tableLayoutPanel1.RowCount-1);
            cellColors[column, row] = GetRandomColor();
            tableLayoutPanel1.Refresh();

            // To change color of the top left cell remove code above and uncomment the following code line: 
            // cellColors[0, 0] = Color.FromArgb( /* define you color */ );
        }

        private Color GetRandomColor()
        {
            return Color.FromArgb(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255));
        }
    }
}

Form1.Designer.cs

namespace WindowsFormsTable
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
            this.button1 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // tableLayoutPanel1
            // 
            this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.tableLayoutPanel1.ColumnCount = 4;
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 46);
            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
            this.tableLayoutPanel1.RowCount = 4;
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.Size = new System.Drawing.Size(410, 256);
            this.tableLayoutPanel1.TabIndex = 1;
            this.tableLayoutPanel1.CellPaint += new System.Windows.Forms.TableLayoutCellPaintEventHandler(this.tableLayoutPanel1_CellPaint);
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(12, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(89, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "Change Color";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(434, 314);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.tableLayoutPanel1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }

        #endregion
        private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
        private System.Windows.Forms.Button button1;
    }
}

enter image description here

Jackdaw
  • 7,626
  • 5
  • 15
  • 33
0

Thanks to Jackdaw's answer I was able to figure our a solution that worked for me:

I am changing colors of the table cells in tableLayoutPanel1_CellPaint event handler, and then calling it from the button's event handler using this script:

this.tableLayoutPanel1.CellPaint += new TableLayoutCellPaintEventHandler(tableLayoutPanel1_CellPaint);

I was missing tableLayoutPanel1.Refresh(); part, but after Jackdaw's answer I noticed and was able to add it. Everything is working correctly now.

The full script looks something like this:

    private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
    {
        if (e.Row == 0 && e.Column == 2)
            e.Graphics.FillRectangle(Brushes.Red, e.CellBounds);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.tableLayoutPanel1.CellPaint += new TableLayoutCellPaintEventHandler(tableLayoutPanel1_CellPaint);
        tableLayoutPanel1.Refresh();
    }

Thank you for your help!