Windows フォーム コントロールのレンダリングRendering a Windows Forms Control

レンダリングとは、ユーザーの画面で視覚的表現を作成するプロセスを指します。Rendering refers to the process of creating a visual representation on a user's screen. Windows フォームは、GDI (新しい Windows グラフィックスライブラリ) を使用してレンダリングを行います。Windows Forms uses GDI (the new Windows graphics library) for rendering. GDI へのアクセスを提供するマネージクラスは、 System.Drawing名前空間とその副名前空間にあります。The managed classes that provide access to GDI are in the System.Drawing namespace and its subnamespaces.

コントロールのレンダリングには、次の要素が含まれます。The following elements are involved in control rendering:

  • 基本クラスSystem.Windows.Forms.Controlによって提供される描画機能。The drawing functionality provided by the base class System.Windows.Forms.Control.

  • GDI グラフィックスライブラリの重要な要素。The essential elements of the GDI graphics library.

  • 描画領域のジオメトリ。The geometry of the drawing region.

  • グラフィックスリソースを解放する手順。The procedure for freeing graphics resources.

コントロールによって提供される描画機能Drawing Functionality Provided by Control

基底クラスControlは、 Paintイベントを通じて描画機能を提供します。The base class Control provides drawing functionality through its Paint event. コントロールは、表示Paintを更新する必要があるときに常にイベントを発生させます。A control raises the Paint event whenever it needs to update its display. .NET Framework のイベントの詳細については、「イベントの処理と発生」を参照してください。For more information about events in the .NET Framework, see Handling and Raising Events.

Paintイベントのイベントデータクラスは、コントロールを描画するために必要なデータ (グラフィックスオブジェクトへのハンドル、および描画する領域を表す四角形オブジェクトを保持します) を保持します。 PaintEventArgsThe event data class for the Paint event, PaintEventArgs, holds the data needed for drawing a control — a handle to a graphics object and a rectangle object that represents the region to draw in. これらのオブジェクトは、次のコードフラグメントに太字で示されています。These objects are shown in bold in the following code fragment.

Public Class PaintEventArgs  
   Inherits EventArgs  
   Implements IDisposable  
  
   Public ReadOnly Property ClipRectangle() As System.Drawing.Rectangle  
      ...  
   End Property  
  
   Public ReadOnly Property Graphics() As System.Drawing.Graphics  
      ...  
   End Property  
   ' Other properties and methods.  
   ...  
End Class  
public class PaintEventArgs : EventArgs, IDisposable {  
public System.Drawing.Rectangle ClipRectangle {get;}  
public System.Drawing.Graphics Graphics {get;}  
// Other properties and methods.  
...  
}  

Graphicsは、このトピックの後半の「GDI の説明」で説明されているように、描画機能をカプセル化するマネージクラスです。Graphics is a managed class that encapsulates drawing functionality, as described in the discussion of GDI later in this topic. ClipRectangleRectangle構造体のインスタンスであり、コントロールが描画できる領域を定義します。The ClipRectangle is an instance of the Rectangle structure and defines the available area in which a control can draw. コントロール開発者は、このClipRectangleトピックでClipRectangle後述する「ジオメトリの説明」で説明されているように、コントロールのプロパティを使用してを計算できます。A control developer can compute the ClipRectangle using the ClipRectangle property of a control, as described in the discussion of geometry later in this topic.

コントロールは、継承元OnPaint Controlのメソッドをオーバーライドすることにより、レンダリングロジックを提供する必要があります。A control must provide rendering logic by overriding the OnPaint method that it inherits from Control. OnPaintグラフィックスオブジェクトと、 Graphics ClipRectangleに渡されるPaintEventArgsインスタンスのプロパティを通じて描画する四角形へのアクセスを取得します。OnPaint gets access to a graphics object and a rectangle to draw in through the Graphics and the ClipRectangle properties of the PaintEventArgs instance passed to it.

Protected Overridable Sub OnPaint(pe As PaintEventArgs)  
protected virtual void OnPaint(PaintEventArgs pe);  

基底OnPaint Paintクラスのメソッドは描画機能を実装しませんが、イベントに登録されているイベントデリゲートを呼び出すだけです。 ControlThe OnPaint method of the base Control class does not implement any drawing functionality but merely invokes the event delegates that are registered with the Paint event. をオーバーライドOnPaintする場合は、通常、基本OnPaintクラスのメソッドを呼び出して、登録されてPaintいるデリゲートがイベントを受け取るようにする必要があります。When you override OnPaint, you should typically invoke the OnPaint method of the base class so that registered delegates receive the Paint event. ただし、画面全体を描画するコントロールでは、基本クラスのOnPaintを呼び出さないでください。これにより、ちらつきが発生します。However, controls that paint their entire surface should not invoke the base class's OnPaint, as this introduces flicker. OnPaintイベントをオーバーライドする例については、「方法:進行状況を表示する Windows フォームコントロールを作成します。For an example of overriding the OnPaint event, see the How to: Create a Windows Forms Control That Shows Progress.

注意

コントロールから直接OnPaint呼び出すのではなく、(からControl継承Invalidateされた) メソッドまたはを呼び出すInvalidate他のメソッドを呼び出します。Do not invoke OnPaint directly from your control; instead, invoke the Invalidate method (inherited from Control) or some other method that invokes Invalidate. メソッドInvalidateが呼び出さOnPaintれます。The Invalidate method in turn invokes OnPaint. メソッドはオーバーロードされており、にInvalidate e指定された引数によっては、コントロールが画面領域の一部またはすべてを再描画します。 InvalidateThe Invalidate method is overloaded, and, depending on the arguments supplied to Invalidate e, a control redraws either some or all of its screen area.

基底Controlクラスは、描画に便利な別のメソッドOnPaintBackground (メソッド) を定義します。The base Control class defines another method that is useful for drawing — the OnPaintBackground method.

Protected Overridable Sub OnPaintBackground(pevent As PaintEventArgs)  
protected virtual void OnPaintBackground(PaintEventArgs pevent);  

OnPaintBackgroundウィンドウの背景 (およびその図形) を描画しOnPaintます。また、個々の描画要求が1つPaintのイベントに結合され、その結果、すべての領域を対象とするすべての領域をカバーします。描画.OnPaintBackground paints the background (and thereby the shape) of the window and is guaranteed to be fast, while OnPaint paints the details and might be slower because individual paint requests are combined into one Paint event that covers all areas that have to be redrawn. たとえば、コントロールのグラデーションカラー OnPaintBackgroundの背景を描画する必要がある場合は、を呼び出すことができます。You might want to invoke the OnPaintBackground if, for instance, you want to draw a gradient-colored background for your control.

OnPaintBackgroundはイベントのような用語があり、 OnPaintメソッドと同じ引数を取りOnPaintBackgroundますが、は true のイベントメソッドではありません。While OnPaintBackground has an event-like nomenclature and takes the same argument as the OnPaint method, OnPaintBackground is not a true event method. イベントは存在PaintBackgroundせずOnPaintBackground 、イベントデリゲートを呼び出しません。There is no PaintBackground event and OnPaintBackground does not invoke event delegates. OnPaintBackgroundメソッドをオーバーライドする場合、派生クラスは基底クラスのOnPaintBackgroundメソッドを呼び出す必要がありません。When overriding the OnPaintBackground method, a derived class is not required to invoke the OnPaintBackground method of its base class.

GDI + の基礎GDI+ Basics

クラスGraphicsには、円、三角形、円弧、楕円などのさまざまな図形を描画するためのメソッドと、テキストを表示するためのメソッドが用意されています。The Graphics class provides methods for drawing various shapes such as circles, triangles, arcs, and ellipses, as well as methods for displaying text. 名前System.Drawing空間とその副名前空間には、図形 (円、四角形、円弧など)、色、フォント、ブラシなどのグラフィックス要素をカプセル化するクラスが含まれています。The System.Drawing namespace and its subnamespaces contain classes that encapsulate graphics elements such as shapes (circles, rectangles, arcs, and others), colors, fonts, brushes, and so on. GDI の詳細については、「マネージグラフィックスクラスの使用」を参照してください。For more information about GDI, see Using Managed Graphics Classes. GDI の基本事項については、 「方法:進行状況を表示する Windows フォームコントロールを作成します。The essentials of GDI are also described in the How to: Create a Windows Forms Control That Shows Progress.

描画領域のジオメトリGeometry of the Drawing Region

コントロールClientRectangleのプロパティは、ユーザーの画面上のコントロールで使用できる四角形の領域を指定しますClipRectangle 。またPaintEventArgs 、のプロパティは、実際に描画される領域を指定します。The ClientRectangle property of a control specifies the rectangular region available to the control on the user's screen, while the ClipRectangle property of PaintEventArgs specifies the area that is actually painted. (描画は、引数としてPaintインスタンスをPaintEventArgs受け取るイベントメソッドで行われることに注意してください)。(Remember that painting is done in the Paint event method that takes a PaintEventArgs instance as its argument). コントロールは、コントロールの表示の小さいセクションが変更された場合のように、使用可能な領域の一部だけを描画する必要がある場合があります。A control might need to paint only a portion of its available area, as is the case when a small section of the control's display changes. このような状況では、コントロール開発者は、描画する実際の四角形を計算Invalidateしてに渡す必要があります。In those situations, a control developer must compute the actual rectangle to draw in and pass that to Invalidate. 引数としてInvalidateまたはRegionRectangle受け取るのオーバーロードされたバージョンは、そのClipRectangle引数をPaintEventArgs使用してプロパティを生成します。The overloaded versions of Invalidate that take a Rectangle or Region as an argument use that argument to generate the ClipRectangle property of PaintEventArgs.

次のコードフラグメントは、カスタムFlashTrackBarコントロールが四角形の領域を計算して描画する方法を示しています。The following code fragment shows how the FlashTrackBar custom control computes the rectangular area to draw in. 変数clientは、プロパティClipRectangleを表します。The client variable denotes the ClipRectangle property. 完全なサンプルについては、「方法:進行状況を表示する Windows フォームコントロールを作成します。For a complete sample, see How to: Create a Windows Forms Control That Shows Progress.

Rectangle invalid = new Rectangle(
    client.X + min, 
    client.Y, 
    max - min, 
    client.Height);

Invalidate(invalid);
Dim invalid As Rectangle = New Rectangle( _
    client.X + lmin, _
    client.Y, _
    lmax - lmin, _
    client.Height)

Invalidate(invalid)

グラフィックスリソースの解放Freeing Graphics Resources

グラフィックスオブジェクトは、システムリソースを使用するため、コストが高くなります。Graphics objects are expensive because they use system resources. このようなオブジェクトにはSystem.Drawing.Graphics 、クラスのインスタンスだけでSystem.Drawing.BrushなくSystem.Drawing.Pen、、、およびその他のグラフィックスクラスのインスタンスが含まれます。Such objects include instances of the System.Drawing.Graphics class as well as instances of System.Drawing.Brush, System.Drawing.Pen, and other graphics classes. グラフィックスリソースは、必要なときにのみ作成し、使用が終了したらすぐにリリースすることが重要です。It is important that you create a graphics resource only when you need it and release it soon as you are finished using it. IDisposableインターフェイスを実装する型を作成する場合は、リソースDisposeを解放するために、メソッドの使用が終了したときにメソッドを呼び出します。If you create a type that implements the IDisposable interface, call its Dispose method when you are finished with it in order to free resources.

次のコードフラグメントは、カスタムFlashTrackBarコントロールがリソースをBrush作成および解放する方法を示しています。The following code fragment shows how the FlashTrackBar custom control creates and releases a Brush resource. 完全なソースコードについては、「方法:進行状況を表示する Windows フォームコントロールを作成します。For the complete source code, see How to: Create a Windows Forms Control That Shows Progress.

private Brush baseBackground = null;
Private baseBackground As Brush
base.OnPaint(e);
if (baseBackground == null) {
    if (showGradient) {
        baseBackground = new LinearGradientBrush(new Point(0, 0),
                                                 new Point(ClientSize.Width, 0),
                                                 StartColor,
                                                 EndColor);
    }
    else if (BackgroundImage != null) {
        baseBackground = new TextureBrush(BackgroundImage);
    }
    else {
        baseBackground = new SolidBrush(BackColor);
    }
}
MyBase.OnPaint(e)

If (baseBackground Is Nothing) Then

    If (myShowGradient) Then
        baseBackground = New LinearGradientBrush(New Point(0, 0), _
                                                 New Point(ClientSize.Width, 0), _
                                                 StartColor, _
                                                 EndColor)
    ElseIf (BackgroundImage IsNot Nothing) Then
        baseBackground = New TextureBrush(BackgroundImage)
    Else
        baseBackground = New SolidBrush(BackColor)
    End If

End If
protected override void OnResize(EventArgs e) {
    base.OnResize(e);
    if (baseBackground != null) {
        baseBackground.Dispose();
        baseBackground = null;
    }
}
Protected Overrides Sub OnResize(ByVal e As EventArgs)
    MyBase.OnResize(e)
    If (baseBackground IsNot Nothing) Then
        baseBackground.Dispose()
        baseBackground = Nothing
    End If
End Sub

関連項目See also