web-dev-qa-db-ja.com

ペイントイベントを呼び出す方法

私のプログラムはパネルにテキストを描画しますが、テキストを削除したい場合は再描画する必要があります。

手でペイントイベントを呼び出す(上げる)方法は?

44
Ivan Prodanov

Invalidate()メソッドは、再描画を引き起こします。

MSDNリンク

42
Matthew Vines

フォームまたはコントロールのメソッドには、3つの選択肢があります。

_this.Invalidate();  // request a delayed Repaint by the normal MessageLoop system    
this.Update();      // forces Repaint of invalidated area 
this.Refresh();     // Combines Invalidate() and Update()
_

通常、あなたはInvalidate()を呼び出して、システムにそれを他のScreen更新と結合させます。急いでいる場合は、Refresh()を呼び出す必要がありますが、他のコントロール(特に親)の無効化のために数回連続して再描画されるリスクがあります。

Windows(Win32およびWinForms.Net)がこれを処理する通常の方法は、 MessageQueue が空になるまで待ってから、無効化されたすべての画面領域を処理することです。通常、他の事柄(コントロール)にカスケードする何かが変化する場合にも、それは効率的です。

Update()の最も一般的なシナリオは、forループでプロパティ(ラベルを無効にするlabel1.Textなど)を変更し、そのループが一時的にメッセージループをブロックしている場合です。使用するときはいつでも、代わりにスレッドを使用するべきではないかどうかを自問する必要があります。しかし、答えは常に「はい」ではありません。

86
Henk Holterman

Invalidate()のちらつきが多すぎることがわかりました。これが私の状況です。私が開発しているカスタムコントロールは、Paintイベントを処理することでコンテンツ全体を描画します。

this.Paint += this.OnPaint;

このハンドラーは、実際の描画を行うカスタムルーチンを呼び出します。

private void OnPaint(object sender, PaintEventArgs e)
{
    this.DrawFrame(e.Graphics);
}

スクロールをシミュレートするために、マウスの左ボタンが押されている間にカーソルが移動するたびにコントロールを再描画します。私の最初の選択は、次のようにInvalidate()を使用することでした。

private void RedrawFrame()
{
    var r = new Rectangle(
        0, 0, this.Width, this.Height);

    this.Invalidate(r);
    this.Update();
}

コントロールはOKにスクロールしますが、flickers快適なレベルをはるかに超えています。そこで、コントロールを再描画する代わりに、MouseMoveイベントを処理した直後にカスタムのDrawFrame()メソッドを呼び出すことにしました。これにより、ちらつきのないスムーズなスクロールが実現しました。

private void RedrawFrame()
{
    var g = Graphics.FromHwnd(this.Handle);
    this.DrawFrame(g);
}

このアプローチはすべての状況に適用できるわけではありませんが、これまでのところ私には適しています。

8
user2529145

Refresh()を呼び出すこともできると思います。

5
Brian

Control.invalidateを呼び出すと、Paintイベントが発生します。

4
Otávio Décio

また、コンテキストに応じて、更新によっておそらくより読みやすいコードが作成されます。

3
Simon Nunn

つかいます Control.InvokePaint手動ダブルバッファリングにも使用できます

0
TheNegative