フォーム描画をクリアするには

解決


うなX  2008-04-03 12:06:51  No: 139437  IP: 192.*.*.*

Basic  の  CLS  みたいなのは
どう書くのでしょうか
VisualBasic2008ExpressEditionです

編集 削除
魔界の仮面弁士  2008-04-03 12:35:43  No: 139438  IP: 192.*.*.*

現在、どのようにしてフォームに描画しているのでしょうか?

・Paint イベントに対するイベント応答で e.Graphics で描画
・OnPaint メソッドを実装して、e.Graphics で描画
・CreateGraphics で得た Graphics を使って描画
・Bitmap に描画して、それを BackgroundImage に割り当てる
・フォームではなく、InkPicture コントロール等にペンで描画している
・描画しているわけではなく、Label 等にテキストを出力している
・上記以外の方法


とりあえず、Graphics クラスによる描画だとしたら、
Clear メソッドを試してみてください。

また、CreateGraphics による一時的な描画だとすれば、
Invalidate メソッドとか。

Partial Public Class Form1

  Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
  Handles Button1.Click
    Using G As Graphics = Me.CreateGraphics()
      G.DrawString(Now.ToString(), Me.Font, Brushes.Blue, 0, 0)
    End Using
  End Sub

  Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) _
  Handles Button2.Click
    Me.Invalidate()
  End Sub

End Class

編集 削除
うなX  2008-04-03 19:18:19  No: 139439  IP: 192.*.*.*

魔界の仮面弁士 様
    教えていただき、ありがとうございました。
CreateGraphics による一時的な描画をやっています。
実は、ちょうどCADのように、  マウスの移動に合わせて
固定始点から移動終点まで  線が  移動する状況を
模索していたのですが、  マウスが動く都度
一旦、線を消して、線を描く  ことをしないと
線が増殖します。
Me.Invalidate()  で
NOW表示をボタンで消す例は
うまくいくのですが、
Me.Invalidate()の直後に線を描くと
連続的に使うと、なぜか
線がちらつきます。
ためしに、線を描く直前に、
Form1のサイズのFillRectangleを
Form1の背景色で描いて消すことを思いつきそれで
案外、ちらつかずにできましたが…。

編集 削除
魔界の仮面弁士  2008-04-04 18:13:22  No: 139440  IP: 192.*.*.*

> Me.Invalidate()の直後に線を描くと
> 連続的に使うと、なぜか

描画手順が、少々間違っているかと。

Invalidate は、描画領域を無効化して再描画を促すためのメソッドですが、
呼びだしたからといって、即座に再描画されるというわけではありません。
再描画を行うタイミングは、OS 側で決定されるためです。


マウスポインタの動きを連想してみてください。
マウスをゆっくり動かすと、カーソルは連続した位置に描画されますが、
高速に動かすと、描画が間引かれ、飛び飛びに描画されますよね。

それと同様に、連続して Invalidate を呼び出しても、それらが 1 回の再描画処理に
まとめられてしまう事があります。あるいは、フォームが他のウィンドウの影に
隠れている最中は、再描画の必要が無いので描画処理が後回しにされたりもします。


という事で、Invalidate の「直後」に描画を行うべきではありません。
描画すべきタイミングになると、Paint イベント(OnPaint メソッド)が
発生しますので、このタイミングで e.Graphics で描画してみてください。

たとえば:

Sub Form1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseMove
    Invalidate()
End Sub

Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Me.Paint
    e.Graphics.DrawLine(Pens.Red, Point.Empty, PointToClient(MousePosition))
End Sub


どうしても Paint イベントを使う事ができないのであれば、即座に再描画するために
Refresh や Update を使う事ができますが…その分、再描画のタイミングを自分で
管理する事になるため、個人的にはあまりお薦めしません。
http://dobon.net/vb/dotnet/control/refreshupdateinvalidate.html


> 線がちらつきます。
ちらつきを抑えるために、ControlStyles.DoubleBuffer を使用する事もできます。
いずれにしても、描画処理を Paint イベントで行う必要はありますけれども。
http://www.atmarkit.co.jp/fdotnet/dotnettips/197doublebuf/doublebuf.html


また、頻繁に描き変わる部分とそうでない部分が混在しているような場合は、
頻繁に描き変わる部分だけは、Paint イベント等の一時描画にて処理し、
描き変わらない部分は、BackgroundImage (あるいは、PictureBox.Image )等に
割り当てられた Bitmap に描画しておく、という手法も使えます。


> Form1のサイズのFillRectangleを
全体を塗りつぶすなら、先述した「Clear メソッド」という手もありますね。

編集 削除
うなX  2008-04-05 16:48:09  No: 139441  IP: 192.*.*.*

魔界の仮面弁士 様
たくさん教えていただきありがとうございます。
僕の頭ではなかなかすぐには全部消化できませんが
少しずつ理解したいと思います…。
Invalidateについて詳しいお話ありがとうございました。
Form1_MouseMoveで
Invalidate()だけを書き
Sub Form1_Paintでe.Graphics.DrawLineと書くのですね。
きれいに描けます!

編集 削除