Home > Software engineering >  Can I stack and toggle between Panels with transparent PNG's on top of each other?
Can I stack and toggle between Panels with transparent PNG's on top of each other?

Time:01-16

I am trying to make a form that allows multiple images to appear/disappear based on what buttons the user chooses. This example is just a test that I'm using to try and figure this out. My real project is more complicated, but the same principles apply, and I'm having the same issue.

I have 5 Transparent PNG's that I need to lay on top of one another to appear as one image. I put each one as the background image of a panel, with the backColor of the panel set to transparent. All looks good while in the form editor, but the images don't appear properly, and I don't know why.

I would just like for the buttons to either turn on or turn off the visibility of the image depending on it's state.

the odd part is, everything works as it should when the panels are not stacked on top of each other. But when I stack them, it acts up.

my 5 images/panels and their names

my 5 images/panels stacked

Here is what I have in place for everything:

 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        PicA.Visible = False
        PicB.Visible = False
        PicC.Visible = False
        PicD.Visible = False

    End Sub


'Button All

 Private Sub BtnAll_Click(sender As Object, e As EventArgs) Handles BtnAll.Click

        If PicA.Visible = False Then
            PicA.Visible = True
        Else
            PicA.Visible = False
        End If

        If PicB.Visible = False Then
            PicB.Visible = True
        Else
            PicB.Visible = False
        End If

        If PicC.Visible = False Then
            PicC.Visible = True
        Else
            PicC.Visible = False
        End If
        If PicD.Visible = False Then
            PicD.Visible = True
        Else
            PicD.Visible = False
        End If
    End Sub

'Button A

    Private Sub BtnA_Click(sender As Object, e As EventArgs) Handles BtnA.Click
        If PicA.Visible = True Then
            PicA.Visible = False
        Else
            PicA.Visible = True
        End If
    End Sub

'Button B

    Private Sub BtnB_Click(sender As Object, e As EventArgs) Handles BtnB.Click
        If PicB.Visible = True Then
            PicB.Visible = False
        Else
            PicB.Visible = True
        End If
    End Sub

'Button C

    Private Sub BtnC_Click(sender As Object, e As EventArgs) Handles BtnC.Click
        If PicC.Visible = True Then
            PicC.Visible = False
        Else
            PicC.Visible = True
        End If
    End Sub

'Button D

    Private Sub BtnD_Click(sender As Object, e As EventArgs) Handles BtnD.Click
        If PicD.Visible = True Then
            PicD.Visible = False
        Else
            PicD.Visible = True
        End If
    End Sub

Here is a short clip of what happens when I run the form: https://youtu.be/oG19RNJKjTU

I'm just getting more confused the more I look into it. Does the order of my code make a difference? does the order in which the panels are stacked make a difference?

If anyone knows what I'm doing wrong or if this isn't possible, I would really appreciate it.

Thanks

CodePudding user response:

Just create one custom control, having 5 layers, and turn on/off the layers, and draw the visible ones on top of each other.

The following code creates a very simple image layers control. Each layer has a Visible and an Image property, and when the Visible of each is True it will be displayed otherwise it wont be displayed. The layers will be painted in the revers order of adding, so the last added layer is on top. After adding or removing layers or changing the visibility, Invalidate the control.

Here is the code which is a good start point. You may want to extend it later and add support for automatic refresh after modifying the layers, or add opacity to the layers, or add size mode (like PictureBox), and many other properties based on your requirement.

Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing.Design
Public Class Layer
    Public Property Image As Image
    Public Property Visible As Boolean = True
End Class
Public Class ImageLayersControl
    Inherits Control
    Sub New()
        SetStyle(ControlStyles.SupportsTransparentBackColor, True)
        DoubleBuffered = True
        ResizeRedraw = True
    End Sub
    <Editor(GetType(CollectionEditor), GetType(UITypeEditor))>
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    Public Property Layers As Collection(Of Layer) = New Collection(Of Layer)
    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        For Each l As Layer In Layers
            If (l.Visible And l.Image IsNot Nothing) Then
                e.Graphics.DrawImage(l.Image, 0, 0)
            End If
        Next
    End Sub
End Class

Then add layers in design-time or run-time and make the layers visible or invisible in design time or using code when you need:

Me.ImageLayersControl1.Layers(1).Visible = False
Me.ImageLayersControl1.Invalidate()

Note: The code requires you add reference to System.Design, or replace the editor attribute with <Editor("System.ComponentModel.Design.CollectionEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", GetType(UITypeEditor))>.

  • Related