2009-11-11 4 views
5

通常、OnPaintメソッドをオーバーライドするときに、ペンやブラシなどを作成して処分します。などWinformsでのカスタムコントロールペイントのベストプラクティス?

私もその代わりに静的メンバーとして一度それらを作成し、フォームを閉じたときに、一度にそれらを配置するには、これらのペンやブラシなどを再作成のどこかで読ん、

これは、より良い練習ですか?

良い方法がありますか?

私は、OnPaintが1000s(?)回呼ばれているので、それらを一度しか作成しないのと比較して、GCのための多くの作業を作成すると思います。

答えて

6

ブラシやペンが変わらない場合は、一度作成して再利用する方がいいでしょう。ただし、コントロールが複数のスレッドで使用される可能性がある場合は、ThreadStatic(またはスレッドごとの最初の使用時に初期化する)またはインスタンスメンバーにしてコントロールのDisposeオーバーライド);そうしないと、GDI +オブジェクトを複数のスレッドで同時に使用できないため、再現性のないGDI +エラーが発生します。画像についても同様です。

これらが変更された場合(たとえば、コントロールのサイズに依存するグラデーションブラシを使用する場合)、インスタンスのフィールドに格納し、コントロールのサイズなどが変更されたときに再作成することができます。

ノート、ところで、あなたは、通常の色を使用する場合、.NETのすべての静的ブラシとペンを含むスタティックBrushesPensクラスを使用することができます内蔵の色、およびシステムの色のSystemBrushesSystemPens

+0

おかげで、もう一つ質問がありますか?私は前にコントロールでそれを呼んだことはありません。 –

+1

あなたはそれを呼び出す必要はありません。 .Netは、親コントロールが破棄されたときに呼び出されます(フォームが破棄されたとき)。あなたのメインフォームにある場合、 'Application.Run'呼び出しの終わりに処理されます。 – SLaks

+0

ありがとうございます。もう1つ:)私は一般に1つのフォームしか使用しないので、メインフォームではない別のフォームを作成すると、閉じた後に処分する必要がありますか? –

1

私は、カスタムコントロールのメンバーとしてブラシとペンを用意し、コントロールを破棄するときにそれらを破棄します。これにより、OnPaintが呼び出されるたびに同じブラシ/ペンが再利用されます。

私はそれらを宣言しませんstatic、あなたはあなたのオブジェクトを処分することができます知ることができないので、しかし、SLAKが言及しているように、同時にメモリ内にコントロールのインスタンスが多数ある場合は、ブラシとペンを静的に作成して、アプリケーションの存続期間中に各オブジェクトのインスタンスを1つだけ作成することをお勧めします。

+0

コントロールのインスタンスが多数ある場合、それらを静的にすることは非常に良い考えです。 2つのブラシをぶら下げても問題はありません。 – SLaks

+1

これは良い点です。このコントロールのインスタンスがたくさんある場合は、ブラシとペンを静的にすることをお勧めします。 –

0

最小限のリソース消費で最適化されているため、システムペンとブラシを使用することをお勧めします。

+0

静的な組み込みの色を使用している場合のみ。 – SLaks

2

最後の月にinteresting articleを読んで、別のBufferedGraphicsオブジェクトにすべてのペイントを行い、on_paintメソッドをコントロールのグラフィックスオブジェクトにそのままコピーさせることをお勧めしました。

このように、ペイントは高速で、重要な変更(行の移動やテキストの変更など)が発生した場合にのみ、BufferedGraphicsを更新します。

+1

ええと、それほど優秀ではありません。これは、クリップされた矩形の代わりに完全なコントロールを描画するようないくつかの悪いことを想定しています。ほとんどの場合、これは最速ではありません。さらに、彼は手動で、システムによって提供されたControlStyles.DoubleBufferを使用する代わりに、手動でダブルバッファを作成しています。あなたのOnPaintハンドラからコードを取り出すと良いかもしれませんが、この記事はそれほど良くない "ボーナス"機能を持っています。 –

1

私は本当にあなたが絵を描いているかどうかにかかっています。ユーザーの操作の結果としてのみ再描画されるものをペイントする場合は、パフォーマンスの心配を緩和し、必要なときにすべてのグラフィックオブジェクトを臨機応変に作成することができます。

Dispose()グラフィックに必要なものがすべて揃っていることを確認してください。ペン、ブラシ、リージョン、フォント。これらはすべてGDIオブジェクトであり、GDIハンドルによってシステムに結び付けられています。

何らかの方法でアニメーション化されたグラフィックや、ユーザーがクリックしないで時間が変わるグラフィックスが必要な場合は、すべてのグラフィックオブジェクトを手前に用意してできるだけ再利用してください。ここで適用できるルールは、アニメーションのすべてのフレームを描画する際にメモリを浪費し、ミリ秒を費やす方が良いということです。

最後に、少なくともこの記事では、ダブルバッファリングを使用することを忘れないでください.netコントロールシステムで自動的に、または独自のバックビットマップスタイルにすることを忘れないでください。そしてどのようにコントロールのDisposeメソッドを呼び出します。

はGDI-INGの楽しい:)

関連する問題