why can I run the following code faultless under a button even but not under the form load even?
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
Here is the striptag function if requierd...
Function StripTags(ByVal html As String) As String
' Remove HTML tags.
Return Regex.Replace(html, "<.*?>", "")
End Function
The right way to draw is hardly ever with CreateGraphics
. This will draw something that does not persist. When the area is invalidated such as the form is minimized or another form/app is dragged over it, your shapes will disappear.
You should also turn on Option Strict
. There are numerous type errors in the code. For instance there is no Rectangle
constructor which takes a Decimal
. That is not even the right Class for non integers, but RectangleF
doesn't take a Decimal either.
The core problem is that the form is shown at the end of the form load event. So, your code is running/drawing before the form is visible and nothing is shown. Even if the form was already showing, whatever you draw would not be retained if the user minimized the form or moved another window across it.
' form level list to store the data
Private XY As New List(Of PointF) ' pts
Then in form load event, read the data and add to the list
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
The next thing that happens should be the form being shown and the paint event invoked. The data is used in the Paint Event:
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
If you have other code to add Point data, like a Button click, after you add, change or remove data, use Invalidate
to force a redraw: Me.Invaludate()
is you are drawing to the form, or PictureBox1.Invalidate()
if you are drawing over a control.
The lesson is that now, every time the form needs to be repainted, your shapes will be redrawn as well.