Question

I like to paint multi cells in tablelayoutpanel. I know how to paint for rows and columns as a normal code below:

private void tableLayoutPane1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
  if (e.Row == 3 || e.Row == 4 || e.Row == 5)
  { 
    LinearGradientBrush brush = new LinearGradientBrush(e.CellBounds, Color.White,   Color.Transparent, 90F);
    e.Graphics.FillRectangle(brush, e.CellBounds);
  }
}

But I want to have one rectangle gradient for 3 cells or rows, and other hand a merged gradient for 3 cells or multiple cells.

Was it helpful?

Solution

This can be done by using the Paint event instead of the CellPaint event. The trick is finding out the location of each cell in the table. There are two functions hidden from Intellisense (GetRowHeights() and GetColumnWidths()) that can get you the row heights and the column widths, so you can calculate the location yourself:

void tlp_Paint(object sender, PaintEventArgs e) {
  int[] rowHeights = tlp.GetRowHeights();
  int[] colmWidths = tlp.GetColumnWidths();

  int boxLeft = 0;
  int boxTop = 0;
  int boxRight = 0;
  int boxBottom = 0;

  Rectangle r = Rectangle.Empty;
  for (int y = 0; y < rowHeights.Length; ++y) {
    boxLeft = 0;
    boxRight = 0;
    boxBottom += rowHeights[y];
    for (int x = 0; x < colmWidths.Length; ++x) {
      boxRight += colmWidths[x];
      if (x == 1 && y == 3) {
        r.X = boxLeft;
        r.Y = boxTop;
      }
      if (x == 2 && y == 5) {
        r.Width = boxRight - r.Left;
        r.Height = boxBottom - r.Top;
      }
      boxLeft += colmWidths[x];
    }
    boxTop += rowHeights[y];
  }

  if (!r.IsEmpty) {
    e.Graphics.TranslateTransform(tlp.AutoScrollPosition.X,
                                  tlp.AutoScrollPosition.Y);
    using (var br = new LinearGradientBrush(
                          r,
                          Color.Red,
                          Color.Black,
                          LinearGradientMode.ForwardDiagonal)) {
      e.Graphics.FillRectangle(br, r);
    }
  }
}

I've included a call to e.Graphics.TranslateTransform in case the TableLayoutPanel control has any scrollbars.

Result:

enter image description here

For any flickering issues, try inheriting from the TableLayoutPanel in order to set its DoubleBuffered property to true.

OTHER TIPS

Concept answer

set each cell individually. the first cell should resemble the first third of your gradient the second cell the middle portion and so on.

set your colors manually with System.Drawing.Color.FromArgb(int,int,int,int) or one of the other overloads which ever one fits best

your code structure would change a bit:

if(first cell)...
if(second cell)...

wish I could help more but its been to long for me since I played with winforms

another way may be to draw your cells transparent and draw an appropriate sized rectangle behind them with the gradient you desire.

sorry I have no real code.

I have found a solution for this question with shortcode below:

int x, y, w, h;

private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
  if (e.Row == 1 && e.Column == 0)
  {
    x = e.CellBounds.X;
    y = e.CellBounds.Y;
    w = e.CellBounds.Width;
    h = e.CellBounds.Height;
  }

  if (e.Row == 2 && e.Column == 0)
  {
    h = h + e.CellBounds.Height;
  }

  if (e.Row == 1 && e.Column == 1)
  {
    w = w + e.CellBounds.Width;
  }

  if (e.Row == 3 && e.Column == 3)
  {
    Rectangle rc = new Rectangle(x, y, w, h);
    LinearGradientBrush brush = new LinearGradientBrush(rc, Color.Blue, Color.White, LinearGradientMode.Vertical);
    e.Graphics.FillRectangle(brush, rc);
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top