绘制代码在按钮单击事件中起作用,但在窗体加载中不起作用



为什么我可以在按钮下完美运行以下代码,甚至在表单加载下

也不能运行?
For Each line As String In System.IO.File.ReadAllLines("c:pos.xml")
    If line.Contains("<POS>") = True Then
        Dim tagless As String = StripTags(line)
        Dim parts As String() = tagless.Split(New Char() {","})
        Dim XVAL As Decimal = parts(0)
        Dim YVAL As Decimal = parts(1)
        'paint markers...
        Dim myBrush As New SolidBrush(Color.FromArgb(128, Color.Red))
        Dim formGraphics As System.Drawing.Graphics
        formGraphics = Me.PictureBox1.CreateGraphics()
        formGraphics.FillEllipse(myBrush, New Rectangle(XVAL - 35, YVAL - 35, 70, 70))
        myBrush.Dispose()
        formGraphics.Dispose()
    End If
Next

如果需要,这是条带标签功能...

    Function StripTags(ByVal html As String) As String
    ' Remove HTML tags.
    Return Regex.Replace(html, "<.*?>", "")
End Function

正确的绘画方式几乎不是CreateGraphics。 这将绘制一些不会持续存在的东西。 当该区域无效时,例如窗体最小化或将另一个窗体/应用程序拖动到该区域上,您的形状将消失。

您还应该打开 Option Strict . 代码中存在许多类型错误。 例如,没有Rectangle构造函数采用Decimal。 这甚至不是非整数的正确类,但RectangleF也不采用十进制。


核心问题是表单显示在表单加载事件的末尾。因此,您的代码在窗体可见之前正在运行/绘制,并且不显示任何内容。 即使表单已经显示,如果用户最小化表单或在其上移动另一个窗口,也不会保留您绘制的任何内容。

' form level list to store the data
Private XY As New List(Of PointF)       ' pts

然后在表单加载事件中,读取数据并添加到列表中

For Each line As String In System.IO.File.ReadAllLines("...")
    If line.Contains("<POS>") = True Then
        Dim tagless As String = StripTags(line)
        '                                      c required under Option Strict
        Dim parts As String() = tagless.Split(New Char() {","c})
        ' convert values to single. create a PointF
        Dim ptF As New PointF(Convert.ToSingle(parts(0)), Convert.ToSingle(parts(1)))
        ' add to list
        XY.Add(ptF)
   End If
Next

接下来发生的应该是显示窗体和调用的 paint 事件。 数据在绘制事件中使用:

Dim rectF As RectangleF
Using myB As New SolidBrush(Color.FromArgb(128, Color.Red))
    For Each ptF As PointF In XY
        rectF = New RectangleF(ptF.X - 35, ptF.Y - 35,
                                70, 70)
        e.Graphics.FillEllipse(myB, rectF)
    Next
End Using

如果在添加、更改或删除数据后,有其他代码(如按钮单击)添加 Point 数据,请使用 Invalidate 强制重绘:Me.Invaludate()绘制到窗体,还是PictureBox1.Invalidate()是否在控件上绘制。

教训是,现在,每次需要重新绘制表单时,您的形状也会重新绘制。

最新更新