vb.net VB.NET绘制方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20638943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 16:10:57  来源:igfitidea点击:

VB.NET paint method?

vb.net

提问by Doug Hauf

Is this the best way to paint images on a form? I have most of my experience in Java and little in VB.net. In Java there is repaint() that can be called? There is a Me.refresh(). Is this what you wnat to call when you have something to add to the form or to paint to the form.

这是在表单上绘制图像的最佳方式吗?我在 Java 方面拥有大部分经验,而在 VB.net 方面经验很少。在 Java 中有可以调用的 repaint() 吗?有一个 Me.refresh()。当您要向窗体添加某些内容或要在窗体上绘画时,这是否是您想要调用的。

Class:

班级:

    Public Class Form1

    Private Sub Form1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        ' Create image. 
        Dim newImage As Image = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")

        ' Create Point for upper-left corner of image. 
        Dim ulCorner As New Point(50, 50)

        ' Draw image to screen.
        e.Graphics.DrawImage(newImage, ulCorner)

        Dim newImage2 As Image = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")

        ' Create Point for upper-left corner of image. 
        Dim ulCorner2 As New Point(150, 150)

        ' Draw image to screen.
        e.Graphics.DrawImage(newImage2, ulCorner2)

    End Sub

End Class

I tried this code here with one button on the form with a click event

我在此处使用带有单击事件的表单上的一个按钮尝试了此代码

Public Class Form1
    Dim i As Integer

    Private Sub Form1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

        i = 0

        ' Create image. 
        Dim newImage As Image = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")

        ' Create Point for upper-left corner of image. 
        Dim ulCorner As New Point(50, 50)

        ' Draw image to screen.
        e.Graphics.DrawImage(newImage, ulCorner)

        Dim newImage2 As Image = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")

        ' Create Point for upper-left corner of image. 
        Dim ulCorner2 As New Point(150, 150)

        ' Draw image to screen.
        e.Graphics.DrawImage(newImage2, ulCorner2)

        If i = 5 Then
            ' Create image. 
            Dim newImage3 As Image = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")

            ' Create Point for upper-left corner of image. 
            Dim ulCorner3 As New Point(250, 250)

            ' Draw image to screen.
            e.Graphics.DrawImage(newImage3, ulCorner3)
        End If

    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        i = 5
        Me.Refresh()
    End Sub
End Class

Just Tried this code here:

刚刚在这里尝试了这段代码:

 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        i = 5
        Me.Invalidate()
 End Sub

New Class just Tested:

刚刚测试的新类:

Public Class Form2
    Dim newImage As Image = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")
    Dim newImage2 As Image = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")
    Dim newImage3 As Image = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")

    Private bgImage As Bitmap
    Private srcImages As Image()

    Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)

        Dim img As Bitmap = Me.bgImage

        If (img Is Nothing) Then
            Me.bgImage = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height)
            img = Me.bgImage
        End If

        If (Not Me.srcImages Is Nothing) Then
        End If

        MyBase.OnPaint(e)

    End Sub

    Private Sub _Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.srcImages = New Image(3 - 1) {}
        Me.srcImages(0) = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")
        Me.srcImages(1) = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")
        Me.srcImages(2) = Image.FromFile("C:\Users\itpr13266\Desktop\Pic\article-tip.gif")
    End Sub

    Private Sub _Disposed(sender As Object, e As EventArgs) Handles MyBase.Disposed
        If (Not Me.srcImages Is Nothing) Then
            For Each img As Image In Me.srcImages
                If (Not img Is Nothing) Then
                    img.Dispose()
                End If
            Next
            Me.srcImages = Nothing
        End If
        If (Not Me.bgImage Is Nothing) Then
            Me.bgImage.Dispose()
            Me.bgImage = Nothing
        End If
    End Sub

    Private Sub _Resize(sender As Object, e As EventArgs) Handles MyBase.SizeChanged, MyBase.Resize
        If (Not Me.bgImage Is Nothing) Then
            Me.bgImage.Dispose()
            Me.bgImage = Nothing
        End If
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Me.Invalidate()
    End Sub
End Class

采纳答案by Bj?rn-Roger Kringsj?

Calling Me.Invalidate()invalidates the entire surface of the control and causes the control to be redrawn.

调用Me.Invalidate()会使控件的整个表面无效并导致重新绘制控件。

I also suggest that you don'tload your images in everypaint cycle. You could load the source images in the forms load event and destroy them when the form disposes.

我还建议您不要每个绘制周期加载图像。您可以在表单加载事件中加载源图像并在表单处理时销毁它们。

Public Class Form1

    Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)

        Dim img As Bitmap = Me.bgImage

        If (img Is Nothing) Then
            Me.bgImage = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height)
            img = Me.bgImage
        End If

        'TODO: Draw and paint.
        If (Not Me.srcImages Is Nothing) Then

        End If

        MyBase.OnPaint(e)

    End Sub

    Private Sub _Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.srcImages = New Image(3 - 1) {}
        Me.srcImages(0) = Image.FromFile("...")
        Me.srcImages(1) = Image.FromFile("...")
        Me.srcImages(2) = Image.FromFile("...")
    End Sub

    Private Sub _Disposed(sender As Object, e As EventArgs) Handles MyBase.Disposed
        If (Not Me.srcImages Is Nothing) Then
            For Each img As Image In Me.srcImages
                If (Not img Is Nothing) Then
                    img.Dispose()
                End If
            Next
            Me.srcImages = Nothing
        End If
        If (Not Me.bgImage Is Nothing) Then
            Me.bgImage.Dispose()
            Me.bgImage = Nothing
        End If
    End Sub

    Private Sub _Resize(sender As Object, e As EventArgs) Handles MyBase.SizeChanged, MyBase.Resize
        If (Not Me.bgImage Is Nothing) Then
            Me.bgImage.Dispose()
            Me.bgImage = Nothing
        End If
    End Sub

    Private bgImage As Bitmap
    Private srcImages As Image()

End Class

回答by Hans Passant

The 1st snippet shows no evidence of needing any help. Nothing in the Paint event handler depends on the state of class so there's no reason to force a repaint. Default painting is already good enough.

第一个片段没有显示需要任何帮助的证据。Paint 事件处理程序中的任何内容都不依赖于类的状态,因此没有理由强制重新绘制。默认绘画已经足够好了。

The 2nd snippet does, through the artificial ivariable. You'd always call Me.Invalidate()in such a case, that marks the entire client region of the form as requiring a repaint. The UI then eventually gets a Paint event when nothing more important needs to be done. Using Me.Refresh()works too but is heavy-handed and it is exceedingly rare to need it. I can't think of a good example.

第二个片段是通过人工i变量。Me.Invalidate()在这种情况下,您总是会调用,这会将表单的整个客户区域标记为需要重新绘制。当没有更重要的事情需要做时,UI 最终会得到一个 Paint 事件。使用Me.Refresh()也有效,但操作繁琐,需要它的情况极为罕见。我想不出一个很好的例子。

Note how Invalidate()has some overloads, you can mark just a portion of the window to require repainting. This is an optimization that makes painting more efficient.

请注意Invalidate()如何有一些重载,您可以仅标记窗口的一部分需要重新绘制。这是一种使绘画更有效的优化。

As written, your program is likely to crash after using it for a while. You must call the Dispose() method of the images you load. Take a look at the VB.NET Usingstatement. You'll want to pre-load the images so it doesn't happen while painting and won't happen repeatedly. Following a Winforms programming tutorial or book is highly recommended to avoid these kind of traps.

正如所写,您的程序在使用一段时间后可能会崩溃。您必须调用加载的图像的 Dispose() 方法。查看 VB.NET Using语句。您需要预加载图像,以便在绘画时不会发生,也不会重复发生。强烈建议遵循 Winforms 编程教程或书籍以避免此类陷阱。