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.
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))>
.