1

次のコードをボタンの下でも問題なく実行できるのに、フォームのロードの下では実行できないのはなぜですか?

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
4

1 に答える 1

1

正しい描画方法は、ほとんどありませんCreateGraphics。これは、持続しないものを描画します。フォームが最小化されるか、別のフォーム/アプリがその上にドラッグされるなど、領域が無効になると、図形が消えます。

もオンにする必要がありますOption Strict。コードには多数の型エラーがあります。たとえば、を受け取るRectangleコンストラクターはありませんDecimal。それは非整数の適切なクラスでさえありRectangleFませんが、Decimal も取りません。


中心的な問題は、フォーム ロード イベントの最後にフォームが表示されることです。したがって、フォームが表示される前にコードが実行/描画され、何も表示されません。フォーム既に表示されていたとしても、ユーザーがフォームを最小化したり別のウィンドウを移動したりした場合、描画したものは保持されません。

' 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

次に発生するのは、フォームが表示され、ペイント イベントが呼び出されることです。データはペイント イベントで使用されます。

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

ポイント データを追加する他のコードがある場合 (ボタン クリックなど)、データを追加、変更、または削除した後、Invalidate強制的に再描画します:Me.Invaludate()フォームに描画しているかPictureBox1.Invalidate()、コントロール上に描画しているか。

レッスンは、フォームを再描画する必要があるたびに、形状も再描画されるということです。

于 2016-01-14T14:43:33.140 に答える