【问题标题】:VB.NET How can I check if an image from my resources is loaded in a PictureBox?VB.NET 如何检查我的资源中的图像是否加载到 PictureBox 中?
【发布时间】:2016-08-28 01:14:21
【问题描述】:

我试图让 PictureBox 在按下时更改图像,如果再次按下它将更改为原始图像。我怎样才能做到这一点?这是我的代码。

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

当我运行它时,它给出了以下错误:

Operator '=' is not defined for types "Image" and "Bitmap".

【问题讨论】:

标签: vb.net


【解决方案1】:

嗯,这是一个很好的问题。 My.Resources 属性 getter 中隐藏着一个巨大的熊陷阱,每次使用它都会得到一个 new 位图对象。这有很多后果,位图是非常昂贵的对象,调用它们的 Dispose() 方法对于防止程序内存不足非常重要。并且比较总是会失败,因为它是新对象。 Image 和 Bitmap 的区别只是一个小问题。

只使用一次位图对象至关重要。像这样:

Private asd As Image = My.Resources.asd
Private _stop As Image = My.Resources._stop

现在您可以正确编写此代码,因为您正在比较对象的引用身份:

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

像一个优秀的程序员一样,当你不再使用图像对象时,你会处理它们:

Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
    asd.Dispose()
    _stop.Dispose()
End Sub

还修复了首先分配PictureBox1.Image属性的代码,我们看不到。

【讨论】:

  • 感谢您的回答。我在哪里插入私人图像.....代码?抱歉,我是 VB 新手。
  • 我更新了 sn-p,将它们放在 Form 类中,就在 Click 事件处理程序的上方。
  • 非常感谢!它给出了一个错误,因为你写了 Private stop 并且 stop 是在 VB 中实现的,如果这是有道理的,但我修复了它。
  • 另外,= 在If PictureBox1.Image = asd Then 中不起作用我使用“Is”而不是“=”。
  • @dino 如果你真的需要使用一个与 VB.NET 关键字冲突的变量名,你可以用方括号括起来,比如[stop]
【解决方案2】:

您可以使用 PictureBox 的.Tag 属性来存储信息。为此,我将存储资源名称。

如果您有要使用的资源名称数组,您可以获得下一个(使用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

请酌情更改“Image1”和“Image2”。

Array.IndexOf 将返回 -1 如果搜索的项目不在数组中,但我们将向它添加 1,因此如果 .Tag 没有,它将获得数组的第一项(在索引 0 处)已设置。

如果您有第三张图片,您只需将其名称添加到数组中即可。

PictureBox1.Image?.Dispose() 行处理图像使用的资源 - ? 仅在 PictureBox1.Image 不是 Nothing 时才会这样做。

当您第一次设置 PictureBox 的图像时,请记住适当地设置其 .Tag 属性,以便它按预期运行。

我使用了Dim pb = DirectCast(sender, PictureBox),这样您就可以简单地复制并粘贴不同 PictureBox 的代码,并且代码几乎不需要更改 - 否则您将不得不通过它更新对 PictureBox1 的引用,这可能容易出错。当然,此时您会开始考虑重构它,以免重复代码(“不要重复自己”或 DRY 原则)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-17
    • 2011-09-27
    • 2012-01-17
    • 1970-01-01
    • 2021-11-22
    • 2014-11-30
    • 2021-02-11
    • 1970-01-01
    相关资源
    最近更新 更多