简体   繁体   English

VB.NET如何检查我的资源中的图像是否已加载到PictureBox中?

[英]VB.NET How can I check if an image from my resources is loaded in a PictureBox?

I am trying to make a PictureBox change the image when pressed, and if pressed again it will change to the original image. 我试图使PictureBox在按下时更改图像,如果再次按下,它将更改为原始图像。 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". 

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. My.Resources属性获取器中隐藏着一个巨大的熊陷阱,每次使用它时,都会得到一个新的位图对象。 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. 这会带来很多后果,位图是非常昂贵的对象,并且调用它们的Dispose()方法对于防止程序内存不足非常重要。 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. 还要修复首先分配PictureBox1.Image属性的代码,我们看不到它。

You can use the PictureBox's .Tag property to store information. 您可以使用PictureBox的.Tag属性存储信息。 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). 如果有要使用的资源名称数组,则可以获取下一个(使用Mod从最后一个到第一个(在VB.NET中,数组索引从零开始)环绕)。

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. 请根据需要更改“ Image1”和“ Image2”。

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. 如果搜索的项不在数组中,则Array.IndexOf将返回-1,但是我们要向其添加1,因此如果未设置.Tag ,它将获得数组的第一项(索引为0)。

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 ? PictureBox1.Image?.Dispose()处理图像使用的资源- ? makes it only do that if PictureBox1.Image is not Nothing. 仅当PictureBox1.Image为Nothing时才这样做。

When you first set the image of the PictureBox, remember to set its .Tag property appropriately so that it behaves as intended. 首次设置PictureBox的图像时,请记住适当设置其.Tag属性,以使其表现出预期的效果。

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. 我使用了Dim pb = DirectCast(sender, PictureBox)这样您就可以简单地将代码复制并粘贴到其他PictureBox中,并且代码中几乎没有更改-否则,您必须将对PictureBox1的引用全部更新通过它,可能容易出错。 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). 当然,到那时,您将开始考虑对其进行重构,以便不重复代码(“不要重复自己”或DRY原理)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM