Reputation: 1
I am trying to make a PictureBox change the image when pressed, and if pressed again it will change to the original image. How can I do that? Here is my code.
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
If (PictureBox1.Image = WindowsApplication1.My.Resources.Resources.asd) Then
PictureBox1.Image = WindowsApplication1.My.Resources.Resources._stop()
Else
PictureBox1.Image = WindowsApplication1.My.Resources.Resources.asd()
End If
End Sub
When I run it, it gives the following error:
Operator '=' is not defined for types "Image" and "Bitmap".
Upvotes: 0
Views: 2095
Reputation: 25066
You can use the PictureBox's .Tag
property to store information. For this, I will store the resource name.
If you have an array of the resource names to be used, you can get the next one (using Mod
to wrap around from the last one to the first (zeroth - array indices start at zero in VB.NET) entry).
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
Dim imageResourceNames = {"Image1", "Image2"}
Dim pb = DirectCast(sender, PictureBox)
Dim tag = CStr(pb.Tag)
pb.Image?.Dispose()
Dim nextImage = imageResourceNames((Array.IndexOf(imageResourceNames, tag) + 1) Mod imageResourceNames.Length)
pb.Image = DirectCast(My.Resources.ResourceManager.GetObject(nextImage), Image)
pb.Tag = nextImage
End Sub
Please change "Image1" and "Image2" as appropriate.
Array.IndexOf
will return -1 if the item searched for is not in the array, but we are adding 1 to it so it will get the first item of the array (at index 0) if the .Tag
has not been set.
If you had a third image, you would simply add its name into the array.
The line PictureBox1.Image?.Dispose()
disposes of the resources used by the image - the ?
makes it only do that if PictureBox1.Image
is not Nothing.
When you first set the image of the PictureBox, remember to set its .Tag
property appropriately so that it behaves as intended.
I used Dim pb = DirectCast(sender, PictureBox)
so that you can simply copy-and-paste the code for a different PictureBox and there will be very little to change in the code - otherwise you would have to update the references to PictureBox1 all through it, which can be error-prone. Of course, at that point you would start thinking about refactoring it so that you are not repeating code (the "Don't repeat yourself", or DRY, principle).
Upvotes: 0
Reputation: 942518
Well, it is the good kind of problem to have. There is a massive bear trap hidden in the My.Resources property getters, every time you use it you get a new bitmap object. That has many consequences, bitmaps are very expensive objects and calling their Dispose() method is very important to prevent your program from running out of memory. And comparing will always fail since it is new object. The difference between Image and Bitmap is just a minor problem.
It is crucial to use the bitmap object just once. Like this:
Private asd As Image = My.Resources.asd
Private _stop As Image = My.Resources._stop
Now you can correctly write this code since you are comparing objects for reference identity:
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
If PictureBox1.Image = asd Then
PictureBox1.Image = _stop
Else
PictureBox1.Image = asd
End If
End Sub
And like a good programmer you dispose the image objects when you no longer use them:
Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
asd.Dispose()
_stop.Dispose()
End Sub
Also fix the code that first assigns the PictureBox1.Image property, we can't see it.
Upvotes: 1