この記事では、カスタム コントロールについて説明し、ユーザー コントロールとの違いについて説明します。 カスタム コントロールは視覚的なデザイン サーフェイスを提供せず、ユーザーが指定したコードに依存して独自に描画します。 これは、複数のコントロールを 1 つの再利用可能な単位にグループ化する視覚的なデザイン サーフェイスを提供するユーザー コントロールとは異なります。
カスタム コントロールは、既存のコントロールまたはユーザー コントロールが、必要な UI または対話機能の提供に近付かない場合に使用されます。 完全に実装するには、より多くの労力が必要です。 キーボードとマウスの処理は引き続き Windows フォームによって提供されますが、動作は実装する必要があります。 すべての描画は、 OnPaint メソッドのコードを使用して行われるため、カスタム コントロールで提供されるデザイン サーフェイスはありません。
Timerなどのコンポーネントは、ビジュアル以外のデザイン サーフェイスを介して追加できます。
カスタム コントロールを作成するときに選択できる基本クラスは 2 つあります。
カスタム コントロールの内容をスクロールする必要がない限り、基底クラスとして Control
を使用します。
カスタム コントロールの基本クラスは Controlされているため、すべてのコントロールで共有されている Windows フォーム機能を自動的に継承します。 カスタム コントロールで取得する機能の一部を次に示します。
- キーボードとマウスの入力。
- 固定やドッキングなどのレイアウト動作。
- タブ処理のサポート。
- 最小サイズと最大サイズの制限。
コントロールのビジュアルを描画することを意味する描画は、 OnPaint メソッドをオーバーライドすることによって実現されます。 コントロールの描画方法の詳細については、「コントロールの ペインティングとドローイング」を参照してください。
Visual Studio テンプレートを使用してカスタム コントロールを作成すると、 OnPaint
メソッドが自動的にオーバーライドされます。 テンプレートはこれを行います。なぜなら、コントロールを描画するコードを記述する必要があるからです。 テンプレートによって生成される内容の例を次に示します。
public partial class CustomControl1 : Control
{
public CustomControl1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
}
Public Class CustomControl1
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
'Add your custom paint code here
End Sub
End Class
カスタム コントロールは、 OnPaint メソッドを使用して描画されます。 このメソッドの 1 つの引数は、コントロールをレンダリングするために必要なすべての情報と機能を提供する PaintEventArgs オブジェクトです。
PaintEventArgs
には、コントロールのレンダリングに使用される 2 つのプロパティが用意されています。
OnPaint
メソッドは、コントロールが画面上で描画または更新されるたびに呼び出され、PaintEventArgs.ClipRectangle
オブジェクトは描画が行われる四角形を表します。 コントロール全体を更新する必要がある場合、 PaintEventArgs.ClipRectangle
はコントロール全体のサイズを表します。 コントロールの一部のみを更新する必要がある場合は、再描画する必要がある領域のみを表します。 このような場合の例として、コントロールがユーザー インターフェイス内の別のコントロールによって部分的に隠され、他のコントロールが移動されると、その下のコントロールの新しく公開された部分を再描画する必要があります。
コントロールの OnPaint メソッド内のコードは、コントロールが最初に描画されたとき、およびコントロールが無効化されるたびに実行されます。 コントロールのサイズが変更されるたびにコントロールが再描画されるようにするには、コントロールのコンストラクターに次の行を追加します。
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.ResizeRedraw, True)
次のコード スニペットは、コントロールの端の周囲に複数の色付きの四角形をレンダリングするカスタム コントロールです。
protected override void OnPaint(PaintEventArgs pe)
{
Rectangle rect = this.ClientRectangle;
// Bring the width/height in by 1 pixel so the rectangle is drawn inside the control.
// Otherwise, it kind of overlaps the outside edge.
rect.Width -= 1;
rect.Height -= 1;
Pen[] colorPens = new Pen[] { Pens.Blue, Pens.BlueViolet,
Pens.AliceBlue, Pens.CornflowerBlue,
Pens.Cyan, Pens.DarkCyan };
foreach (Pen pen in colorPens)
{
pe.Graphics.DrawRectangle(pen, rect);
rect.Inflate(-1, -1);
}
// Raise the Paint event so users can custom paint if they want.
base.OnPaint(pe);
}
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim rect As Rectangle = Me.ClientRectangle
'Bring the width/height in by 1 pixel so the rectangle is drawn inside the control.
'Otherwise, it kind of overlaps the outside edge.
rect.Width -= 1
rect.Height -= 1
Dim colorPens As Pen() = {Pens.Blue, Pens.BlueViolet,
Pens.AliceBlue, Pens.CornflowerBlue,
Pens.Cyan, Pens.DarkCyan}
For Each curPen As Pen In colorPens
e.Graphics.DrawRectangle(curPen, rect)
rect.Inflate(-1, -1)
Next
'Raise the Paint event so users can custom paint if they want.
MyBase.OnPaint(e)
End Sub
前のコードでは、次の図のようなコントロールが作成されます。
OnPaint
コードがコントロールをクリアしたり、色で塗りつぶしたりしていない場合でも、コントロールの背景はSystemColors.Controlの色で塗りつぶされていることに注意してください。 背景は実際には、OnPaint
が呼び出される前に、OnPaintBackground(PaintEventArgs) メソッドによって描画されます。 コントロールの背景の描画を処理するには、 OnPaintBackground
をオーバーライドします。 このメソッドの既定の実装では、 BackColor プロパティと BackgroundImage プロパティによって設定された色とイメージをそれぞれ描画します。