このブラウザーはサポートされなくなりました。
Microsoft Edge にアップグレードすると、最新の機能、セキュリティ更新プログラム、およびテクニカル サポートを利用できます。
コントロールのカスタム ペインティングは、Windows フォームによって簡単に実行できる多数の複雑なタスクの 1 つです。 カスタム コントロールを作成する場合、コントロールのグラフィカルな外観を処理するために使用できる多くのオプションがあります。カスタム コントロール(つまり、Controlから継承するコントロール)を作成する場合は、コードを使用してそのグラフィカル表現をレンダリングします。
複合コントロール (UserControlまたは既存の Windows フォーム コントロールのいずれかを継承するコントロール) を作成する場合は、標準のグラフィカル表現をオーバーライドし、独自のグラフィックス コードを提供できます。
新しいコントロールを作成せずに既存のコントロールにカスタム レンダリングを提供する場合は、コントロールを描画できるPaint イベントを処理します。
コントロールのレンダリングには、次の要素が関係します。
基底クラスControl のPaint イベントを通じて描画機能が提供されます。 コントロールは、表示を更新する必要があり、描画が完了するたびに、Paint イベントを発生させます。 .NET のイベントの詳細については、「イベントの処理と発生」を参照してください。
Paint イベントのイベント データ クラスであるPaintEventArgs により、コントロールの描画に必要なデータである、グラフィックス オブジェクトへのハンドルと、描画する領域を表す四角形が保持されます。
public class PaintEventArgs : EventArgs, IDisposable{ public System.Drawing.Rectangle ClipRectangle {get;} public System.Drawing.Graphics Graphics {get;} // Other properties and methods.}Public Class PaintEventArgs Inherits EventArgs Implements IDisposable Public ReadOnly Property ClipRectangle As System.Drawing.Rectangle Public ReadOnly Property Graphics As System.Drawing.Graphics ' Other properties and methods.End ClassGraphics は、描画機能をカプセル化するマネージド クラスです (この記事の GDI に関する説明で後述します)。ClipRectangle はRectangle 構造体のインスタンスであり、コントロールで描画できる領域を定義します。 コントロール開発者は、コントロールのClipRectangle プロパティを使用して、ClipRectangle を計算できます (この記事のジオメトリに関する説明で後述します)。
コントロールはOnPaint から継承するControl メソッドをオーバーライドすることにより、レンダリング ロジックを提供する必要があります。OnPaint は、渡されたGraphics インスタンスのClipRectangle およびPaintEventArgs プロパティを通じて、グラフィックス オブジェクトと描画対象の四角形にアクセスします。
次のコードでは、System.Drawing 名前空間を使用しています。
protected override void OnPaint(PaintEventArgs e){ // Call the OnPaint method of the base class. base.OnPaint(e); // Declare and instantiate a new pen that will be disposed of at the end of the method. using var myPen = new Pen(Color.Aqua); // Create a rectangle that represents the size of the control, minus 1 pixel. var area = new Rectangle(new Point(0, 0), new Size(this.Size.Width - 1, this.Size.Height - 1)); // Draw an aqua rectangle in the rectangle represented by the control. e.Graphics.DrawRectangle(myPen, area);}Protected Overrides Sub OnPaint(e As PaintEventArgs) MyBase.OnPaint(e) ' Declare and instantiate a drawing pen. Using myPen = New System.Drawing.Pen(Color.Aqua) ' Create a rectangle that represents the size of the control, minus 1 pixel. Dim area = New Rectangle(New Point(0, 0), New Size(Me.Size.Width - 1, Me.Size.Height - 1)) ' Draw an aqua rectangle in the rectangle represented by the control. e.Graphics.DrawRectangle(myPen, area) End UsingEnd Sub基底クラスOnPaint のControl メソッドによって描画機能は実装されず、Paint イベントに登録されているイベント デリゲートを単に呼び出すだけです。OnPaint をオーバーライドするときは、登録されているデリゲートでOnPaint イベントを受け取ることができるように、通常、基底クラスのPaint メソッドを呼び出す必要があります。 ただし、画面全体を描画するコントロールの場合は、基底クラスのOnPaint を呼び出すことはできません。これによって、ちらつきが生じるためです。
注
コントロールから直接OnPaint を呼び出さないでください。代わりに、Invalidate メソッド (Control から継承)、またはInvalidate を呼び出す他のメソッドを呼び出します。Invalidate メソッドによって、OnPaint が呼び出されます。Invalidate メソッドはオーバーロードされ、Invalidatee に指定された引数に応じて、その画面領域の一部または全体が再描画されます。
コントロールが最初に描画されるときと、更新されるたびに、コントロールのOnPaint メソッドのコードが実行されます。 サイズが変更されるたびにコントロールが確実に再描画されるようにするには、コントロールのコンストラクターに次の行を追加します。
SetStyle(ControlStyles.ResizeRedraw, true);SetStyle(ControlStyles.ResizeRedraw, True)基底クラスControl により、描画に便利なもう 1 つのメソッドOnPaintBackground が定義されています。
protected virtual void OnPaintBackground(PaintEventArgs e);Protected Overridable Sub OnPaintBackground(e As PaintEventArgs)OnPaintBackground を使用すると、ウィンドウの背景 (およびそのシェイプ) が描画され、高速な処理が保証されます。一方、OnPaint を使用すると、細部が描画され、個々の描画要求が、再描画の必要なすべての領域をカバーする 1 つのPaint イベントに結合されるため、処理が遅くなる場合があります。 たとえば、コントロールのグラデーション カラーの背景を描画する必要がある場合は、OnPaintBackground を呼び出す必要がある場合があります。
OnPaintBackground にはイベントのような命名法があり、OnPaint メソッドと同じ引数を受け取りますが、OnPaintBackground は本当のイベント メソッドではありません。PaintBackground イベントは存在せず、OnPaintBackground でイベント デリゲートは呼び出されません。OnPaintBackground メソッドをオーバーライドするとき、派生クラスで基底クラスのOnPaintBackground メソッドを呼び出す必要はありません。
Graphics クラスには、円、三角形、円弧、楕円などのさまざまなシェイプを描画するためのメソッドと、テキストを表示するためのメソッドが用意されています。System.Drawing 名前空間には、シェイプ (円、四角形、円弧など)、色、フォント、ブラシなどのグラフィックス要素をカプセル化する名前空間とクラスが含まれています。
コントロールのClientRectangle プロパティにより、ユーザーの画面上でコントロールが使用できる四角形の領域が指定されています。一方、ClipRectangle のPaintEventArgs プロパティにより、描画される領域が指定されます。 コントロールの表示の小さいセクションが変更された場合のように、コントロールで使用可能な領域の一部だけを描画することが必要になる場合があります。 そのような状況では、コントロール開発者は、実際に描画する四角形を計算し、それをInvalidate に渡す必要があります。 引数としてInvalidate またはRectangle を受け取るRegion のオーバーロードされたバージョンにより、その引数を使用して、ClipRectangle のPaintEventArgs プロパティが生成されます。
グラフィックス オブジェクトは、システム リソースを使用するため、コストが高くなります。 そのようなオブジェクトには、System.Drawing.Graphics クラスのインスタンスと、System.Drawing.Brush、System.Drawing.Pen、およびその他のグラフィックス クラスのインスタンスが含まれます。 必要なときにだけグラフィックス リソースを作成し、使い終わったらすぐに解放することが重要です。IDisposable インターフェイスが実装されている型のインスタンスを作成する場合は、終了したらそのDispose メソッドを呼び出してリソースを解放します。
このページはお役に立ちましたか?
このトピックについてサポートが必要ですか?
このトピックの意図を把握したり、理解を深めたりするために Ask Learn を使ってみませんか?
このページはお役に立ちましたか?
このトピックの意図を把握したり、理解を深めたりするために Ask Learn を使ってみませんか?