none
TableLayoutPanel CellPaint Event Repeatedly raises RRS feed

  • Question

  • Hi All

    I have a curious debugging problem.  I have creates a TableLayoutPanel Control in which I create columns and use the FillRectangle  function to update a cell in the TableLayoutPanel with data the user enters.

    While degugging, I noticed that the paint function is raised repeatedly. i.e. 7 or 8 times, instead of only once.  Is this normal for the Cellpaint function.  I have attached a sample of the code. 

    I normal don't use the paint function so I am not sure if this is common.  It seems inefficient.

     
        Public Sub TableUserLayout_Paint(sender As Object, e As TableLayoutCellPaintEventArgs) Handles TableLayoutPanel1.CellPaint
      
           TableLayoutPanel1_CellPaint(sender, e)
    
        End Sub
    
        Private Sub TableLayoutPanel1_CellPaint(ByVal sender As Object, ByVal e As TableLayoutCellPaintEventArgs) _
            Handles TableLayoutPanel1.CellPaint
     
            Dim g As Graphics = e.Graphics
            Dim numberofRects As Integer = TableLayoutPanel1.RowCount
            Dim tempdebugtest As Integer = (EditCoaxLine.SectionNo_NumericUpDown.Value - 1)
    
            MyTemprectangles.Clear() 'Array of calculated data for the user rectangles
    
            Dim i As Integer = 0
    
            For Each ctrl As Control In TableLayoutPanel1.Controls
    
                If TypeOf ctrl Is LayoutUserControl Then
    
                    Dim cellPos As TableLayoutPanelCellPosition = TableLayoutPanel1.GetCellPosition(ctrl) 'Debug check of row/column location
                    ctrl.Visible = False 
    
                    For Each K As Myrectangle In Myrectangles  'Data for each column which is different depending on user input
    
                        If (i + 1) = K.TableRowPosition Then 'Check if the right column
    
                            MyTemprectangles.Add(New Myrectangle(i, K.myPen, K.RectangleToDraw))  'Add data to a temp array
    
                        End If
    
                    Next
    
                    For Each L As Myrectangle In MyTemprectangles
    
                        'Draw recyangles to screen.
                        g.FillRectangle(L.myPen, L.RectangleToDraw)  'Draw rectangles in cell
    
                    Next
                    MyTemprectangles.Clear() 'clears temp array
                    i += 1
                Else
                    ctrl.Visible = True 
                    ctrl.Text = i  'Label for each column 
                End If
            Next
    
       End Sub


    • Edited by Nuadha1 Monday, April 30, 2018 12:55 AM
    Monday, April 30, 2018 12:54 AM

All replies

  •  I believe you will find that the CellPaint event is called once for each cell in the TableLayoutPanel.

     If you check the properties in the TableLayoutCellPaintEventArgs Class that is passed to the CellPaint event's (e) parameter you will find that the Row and Column properties change each time it is called.  So does the CellBounds property too.

     You should be able to just use the Row and Column properties from the TableLayoutCellPaintEventArgs to detect which cell is currently being painted.  Then you can adjust whatever you need according to the Row and Column.  You would also find the CellBounds property to be handy too.

     For example,  I have a TableLayoutPanel with 4 cells and use the Row and Column properties to determine what color to fill them with.  Notice I am not using a loop to iterate through all the cells.

    Public Class Form1
    
        Private Sub TableLayoutPanel1_CellPaint(sender As Object, e As TableLayoutCellPaintEventArgs) Handles TableLayoutPanel1.CellPaint
            Dim brsh As Brush = Nothing
            Select Case e.Column
                Case 0
                    If e.Row = 0 Then
                        brsh = Brushes.Red 'if it is Column 0, Row 0
                    Else
                        brsh = Brushes.Green 'if it is Column 0, Row 1
                    End If
                Case 1
                    If e.Row = 0 Then
                        brsh = Brushes.Blue 'if it is Column 1, Row 0
                    Else
                        brsh = Brushes.Yellow 'if it is Column 1, Row 1
                    End If
            End Select
            e.Graphics.FillRectangle(brsh, e.CellBounds) 'fills the (CellBounds) with the calculated brush color
        End Sub
    
    End Class
     

     

     


    If you say it can`t be done then i`ll try it

    Monday, April 30, 2018 1:53 AM
  • You already have e.Graphics in the paint event sub. There is only overhead then creating new graphics g for no purpose. Plus you never dispose of g.

    e.Graphics.FillRectangle(L.myPen, L.RectangleToDraw)


    La vida loca

    Monday, April 30, 2018 6:51 PM
  • You already have e.Graphics in the paint event sub. There is only overhead then creating new graphics g for no purpose. Plus you never dispose of g.

    e.Graphics.FillRectangle(L.myPen, L.RectangleToDraw)


    La vida loca


    Creating a variable for e.Graphics just shortens the code that needs to be typed.  It is not a new instance of graphics so there is no additional overhead (beyond the tiny amount needed for the new variable).  And since "g" is just a variable pointing to the existing e.Graphics, and you never dispose a graphics object that you do not create yourself, there is no need to call dispose.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Monday, April 30, 2018 7:27 PM
    Moderator
  •  
        Public Sub TableUserLayout_Paint(sender As Object, e As TableLayoutCellPaintEventArgs) Handles TableLayoutPanel1.CellPaint
      
           TableLayoutPanel1_CellPaint(sender, e)
    
        End Sub
    
    


    Also, there is no need for the above code.  This is actually causing the CellPaint event to be raised an extra time.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Monday, April 30, 2018 7:30 PM
    Moderator
  • You already have e.Graphics in the paint event sub. There is only overhead then creating new graphics g for no purpose. Plus you never dispose of g.

    e.Graphics.FillRectangle(L.myPen, L.RectangleToDraw)


    La vida loca


    Creating a variable for e.Graphics just shortens the code that needs to be typed.  It is not a new instance of graphics so there is no additional overhead (beyond the tiny amount needed for the new variable).  And since "g" is just a variable pointing to the existing e.Graphics, and you never dispose a graphics object that you do not create yourself, there is no need to call dispose.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Creating a graphics object is not the same as what you suggest IMO. But then I don't have all the answers. We typically dispose of graphics object in using statement.

    Public NotInheritable Class Graphics
     Inherits MarshalByRefObject
     Implements IDisposable, IDeviceContex


    La vida loca

    Monday, April 30, 2018 9:26 PM
  •  Hi John,

     Not to stir up anything but,  Reed is just saying that OP is only creating a variable g that hold a reference to e.Graphics,  they are not actually creating a new Graphics object.  OP is using the line below to get the reference to e.Graphics.  If you dispose of that reference,  you will actually be disposing e.Graphics.  That would cause an exception when the CellPaint event was called the second time.  8)

    Dim g As Graphics = e.Graphics


    If you say it can`t be done then i`ll try it

    Monday, April 30, 2018 10:33 PM
  •  Hi John,

     Not to stir up anything but,  Reed is just saying that OP is only creating a variable g that hold a reference to e.Graphics,  they are not actually creating a new Graphics object.  OP is using the line below to get the reference to e.Graphics.  If you dispose of that reference,  you will actually be disposing e.Graphics.  That would cause an exception when the CellPaint event was called the second time.  8)

    Dim g As Graphics = e.Graphics


    If you say it can`t be done then i`ll try it


    Alrighty then... :)

    La vida loca

    Monday, April 30, 2018 10:44 PM