Search code examples
c#.netvb.netpaintpaintevent

Perform Paint in top of multiple controls


I have a short problem. How can i paint this kind of image in top of any controls like textbox etc.

This is my code:

Private Sub GroupBox6_Paint(sender As Object, e As PaintEventArgs) Handles GroupBox6.Paint
    If txtStatus.Text = "Cancelled" Then
        Try
            Dim newImage As Image = Image.FromFile(FOLDER_PATH & "\completed.png")
            Dim x As Single = ((GroupBox6.Width / 2) - (463 / 4))
            Dim y As Single = 10
            Dim width As Single = 463 / 2
            Dim height As Single = 242 / 2
            e.Graphics.DrawImage(newImage, x, y, width, height)
        Catch ex As Exception
        End Try
     End If
End Sub

And this is my Output:

enter image description here

so my goal is to paint the image Completed in top of textbox, label inside my groupbox any idea?


Solution

  • You need two bitmaps and a picturebox for this to work. The first one is the png image and the second one the picturebox image:

    Private pngImage, picBoxImage As Image
    

    In form load event initialize the two images:

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        pngImage = Image.FromFile(FOLDER_PATH & "\completed.png") //load it once
        picBoxImage = CType(pngImage.Clone, Image)
    
        PictureBox1.Size = New Size(CInt(463 / 2), CInt(242 / 2))
        PictureBox1.Parent = GroupBox6
        PictureBox1.Image = picBoxImage
        PictureBox1.Visible = False //you dont want it at the beggining
    End Sub
    

    The sub to show the picturebox:

    Private Sub ShowCompletedMessage()
        Dim screenLocation As Point
        Dim gr As Graphics
        //you can pass these values as parameters in the sub if you want to make the code more generic
        Dim x As Integer = CInt(((GroupBox6.Width / 2) - (463 / 4)))
        Dim y As Integer = 10
        Dim width As Integer = CInt(463 / 2)
        Dim height As Integer = CInt(242 / 2)
    
        //Ensure that picturebox is not visible. If it is you don't need to take a screenshot
        If PictureBox1.Visible = True Then
            Return
        End If
    
        gr = Graphics.FromImage(picBoxImage)
    
        //you need to transform the coordinates to screen ones
        screenLocation = GroupBox6.PointToScreen(New Point(x, y))
    
        //draw the portion of the screen to your bitmap
        gr.CopyFromScreen(screenLocation.X, screenLocation.Y, 0, 0, New Size(width, height), CopyPixelOperation.SourceCopy)
    
        //draw the png image on top
        gr.DrawImage(pngImage, 0, 0, width, height)
    
        PictureBox1.Location = New Point(x, y)
        PictureBox1.BringToFront()
        PictureBox1.Visible = True
    
        gr.Dispose()
        gr = Nothing
    
    
        Return
    
    End Sub
    

    Every time you want to show the message call the above sub. You decide from where and when. You need to hide picturebox if you don't need it anymore

    PictureBox1.Visible = False