方法 : シンプルな Windows フォーム コントロールを開発する

ここでは、カスタム Windows フォーム コントロールの作成手順を示します。 この手順では、Text プロパティの配列を変更できるシンプルなコントロールを作成します。 このコントロールでは、イベントの発生や処理は行われません。

シンプルなカスタム コントロールを作成するには

  1. System.Windows.Forms.Control から派生するクラスを定義します。

    Public Class FirstControl
       Inherits Control
    
    End Class
    
    public class FirstControl:Control{}
    
  2. プロパティを定義します。 コントロールは Control クラスから多数のプロパティを継承するため、プロパティの定義は必須ではありません。ただし、ほとんどのカスタム コントロールでは追加プロパティを定義します。 TextAlignment というプロパティを定義するコード片を次に示します。このプロパティは、 FirstControl が、Control から継承した Text プロパティの表示形式を設定するときに使用するプロパティです。 プロパティの定義の詳細については、「プロパティの概要」を参照してください。

    ' ContentAlignment is an enumeration defined in the System.Drawing
    ' namespace that specifies the alignment of content on a drawing 
    ' surface.
    Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft
    
    <Category("Alignment"), Description("Specifies the alignment of text.")> _
    Public Property TextAlignment() As ContentAlignment
    
       Get
          Return alignmentValue
       End Get
       Set
          alignmentValue = value
    
          ' The Invalidate method invokes the OnPaint method described 
          ' in step 3.
          Invalidate()
       End Set
    End Property
    
    // ContentAlignment is an enumeration defined in the System.Drawing
    // namespace that specifies the alignment of content on a drawing 
    // surface.
    private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;
    

    コントロールのビジュアル表示を変更するプロパティを設定するには、Invalidate メソッドを呼び出して、コントロールを再描画する必要があります。 Invalidate は基本クラス Control で定義されます。

  3. Control から継承された OnPaint プロテクト メソッドをオーバーライドして、レンダリング ロジックをコントロールに追加します。 OnPaint をオーバーライドしないと、作成するコントロールがそのコントロール自体を描画できません。 OnPaint メソッドが Control から継承した Text プロパティを、alignmentValue フィールドによって指定された配置で表示するコード片を次に示します。

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
    
       MyBase.OnPaint(e)
       Dim style As New StringFormat()
       style.Alignment = StringAlignment.Near
       Select Case alignmentValue
          Case ContentAlignment.MiddleLeft
             style.Alignment = StringAlignment.Near
          Case ContentAlignment.MiddleRight
             style.Alignment = StringAlignment.Far
          Case ContentAlignment.MiddleCenter
             style.Alignment = StringAlignment.Center
       End Select
    
       ' Call the DrawString method of the System.Drawing class to write   
       ' text. Text and ClientRectangle are properties inherited from
       ' Control.
       e.Graphics.DrawString( _
           me.Text, _
           me.Font, _
           New SolidBrush(ForeColor), _
           RectangleF.op_Implicit(ClientRectangle), _
           style)
    
    End Sub
    
    protected override void OnPaint(PaintEventArgs e) 
    {   
        base.OnPaint(e);
        StringFormat style = new StringFormat();
        style.Alignment = StringAlignment.Near;
        switch (alignmentValue) 
        {
            case ContentAlignment.MiddleLeft:
                style.Alignment = StringAlignment.Near;
                break;
            case ContentAlignment.MiddleRight:
                style.Alignment = StringAlignment.Far;
                break;
            case ContentAlignment.MiddleCenter:
                style.Alignment = StringAlignment.Center;
                break;
        }
    
        // Call the DrawString method of the System.Drawing class to write   
        // text. Text and ClientRectangle are properties inherited from
        // Control.
        e.Graphics.DrawString(
            Text, 
            Font, 
            new SolidBrush(ForeColor), 
            ClientRectangle, style);
    
    } 
    
  4. コントロールの属性を指定します。 デザイン時には、ビジュアル デザイナーではこれらの属性を使用して、コントロール、コントロールのプロパティとイベントが適切に表示されます。 TextAlignment プロパティに属性を適用するコード片を次に示します。 Visual Studio などのデザイナーでは、次のコード片に示されている Category 属性によって、プロパティが論理カテゴリの下に表示されます。 Description 属性が適用されている場合には、TextAlignment プロパティが選択されると、[プロパティ] ウィンドウ下部に説明文字列が表示されます。 属性の詳細については、「コンポーネントのデザイン時属性」を参照してください。

    <Category("Alignment"), Description("Specifies the alignment of text.")> _
    Public Property TextAlignment() As ContentAlignment
    
    [
    Category("Alignment"),
    Description("Specifies the alignment of text.")
    ]
    
  5. (省略可能) コントロールに対してリソースを指定します。 コントロールに対してビットマップなどのリソースを指定するには、コンパイラ オプション (C# の /res など) を使用して、コントロールにリソースをパッケージ化します。 実行時には、ResourceManager クラスのメソッドを使用してリソースを取得できます。 リソースの作成と使用の詳細については、「アプリケーションのリソース」を参照してください。

  6. コンパイルしてコントロールを配置します。 FirstControl をコンパイルして配置するには、次の手順に従います。

    1. 次のサンプルのコードをソース ファイル (FirstControl.cs または FirstControl.vb など) に保存します。

    2. ソース コードをコンパイルして、アセンブリを生成します。アプリケーションのディレクトリにこのアセンブリを保存します。 この処理を行うには、ソース ファイルが格納されているディレクトリで次のコマンドを実行します。

      vbc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.vb
      
      csc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.cs
      

      /t:library コンパイラ オプションによって、作成するアセンブリが実行可能ファイルではなくライブラリであることがコンパイラに指示されます。 /out オプションには、アセンブリの名前とパスを指定します。 /r オプションには、コードがアセンブリを参照するときのアセンブリ名を指定します。 上記のコード例で作成されるアセンブリは、開発者が作成したアプリケーションだけで使用できるプライベート アセンブリです。 したがって、このアセンブリを各自のアプリケーションのディレクトリに保存する必要があります。 配布用にコントロールをパッケージ化および配置する方法の詳細については、「.NET Framework およびアプリケーションの配置」を参照してください。

FirstControl のコードのサンプルを次に示します。 このコントロールは、CustomWinControls 名前空間に格納されています。 名前空間では、関連する型を論理的にグループ化できます。 コントロールを作成するには、既存の名前空間を使用するか、または名前空間を新規作成して使用します。 C# では、using 宣言 (Visual Basic の場合は Imports) を使用すると、名前空間から型へアクセスするときに、型の完全限定名を使用する必要がありません。 次の例では、using 宣言によって、コードは完全修飾名 System.Windows.Forms.Control を使用せずに単純に Control として System.Windows.Forms から Control クラスにアクセスできます。

Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms


Public Class FirstControl
   Inherits Control

   Public Sub New()
   End Sub 


   ' ContentAlignment is an enumeration defined in the System.Drawing
   ' namespace that specifies the alignment of content on a drawing 
   ' surface.
   Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft

   <Category("Alignment"), Description("Specifies the alignment of text.")> _
   Public Property TextAlignment() As ContentAlignment

      Get
         Return alignmentValue
      End Get
      Set
         alignmentValue = value

         ' The Invalidate method invokes the OnPaint method described 
         ' in step 3.
         Invalidate()
      End Set
   End Property


   Protected Overrides Sub OnPaint(e As PaintEventArgs)

      MyBase.OnPaint(e)
      Dim style As New StringFormat()
      style.Alignment = StringAlignment.Near
      Select Case alignmentValue
         Case ContentAlignment.MiddleLeft
            style.Alignment = StringAlignment.Near
         Case ContentAlignment.MiddleRight
            style.Alignment = StringAlignment.Far
         Case ContentAlignment.MiddleCenter
            style.Alignment = StringAlignment.Center
      End Select

      ' Call the DrawString method of the System.Drawing class to write   
      ' text. Text and ClientRectangle are properties inherited from
      ' Control.
      e.Graphics.DrawString( _
          me.Text, _
          me.Font, _
          New SolidBrush(ForeColor), _
          RectangleF.op_Implicit(ClientRectangle), _
          style)

   End Sub

End Class
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace CustomWinControls
{
    public class FirstControl : Control
    {

        public FirstControl()
        {

        }

        // ContentAlignment is an enumeration defined in the System.Drawing
        // namespace that specifies the alignment of content on a drawing 
        // surface.
        private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;

        [
        Category("Alignment"),
        Description("Specifies the alignment of text.")
        ]
        public ContentAlignment TextAlignment 
        {

            get 
            {
                return alignmentValue;
            }
            set 
            {
                alignmentValue = value;

                // The Invalidate method invokes the OnPaint method described 
                // in step 3.
                Invalidate(); 
            }
        }


        protected override void OnPaint(PaintEventArgs e) 
        {   
            base.OnPaint(e);
            StringFormat style = new StringFormat();
            style.Alignment = StringAlignment.Near;
            switch (alignmentValue) 
            {
                case ContentAlignment.MiddleLeft:
                    style.Alignment = StringAlignment.Near;
                    break;
                case ContentAlignment.MiddleRight:
                    style.Alignment = StringAlignment.Far;
                    break;
                case ContentAlignment.MiddleCenter:
                    style.Alignment = StringAlignment.Center;
                    break;
            }

            // Call the DrawString method of the System.Drawing class to write   
            // text. Text and ClientRectangle are properties inherited from
            // Control.
            e.Graphics.DrawString(
                Text, 
                Font, 
                new SolidBrush(ForeColor), 
                ClientRectangle, style);

        } 
    }
}

フォームでのカスタム コントロールの使用

FirstControl を使用するシンプルなフォームの例を次に示します。 この例では、FirstControl のインスタンスを 3 つ作成します。それぞれのインスタンスでは、TextAlignment プロパティに異なる値が設定されます。

このサンプルをコンパイルして実行するには

  1. 次に示すサンプルのコードをソース ファイル (SimpleForm.cs または SimpleForms.vb) に保存します。

  2. ソース ファイルが格納されているディレクトリで次のコマンドを実行することにより、実行可能アセンブリへソース コードをコンパイルします。

    vbc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.vb
    
    csc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.cs
    

    CustomWinControls.dll は、 FirstControl クラスが含まれているアセンブリです。 フォームがこのアセンブリへアクセスできるように、このアセンブリはソース ファイル (SimpleForm.cs または SimpleForms.vb) と同じディレクトリに格納されている必要があります。

  3. 次に示すコマンドで SimpleForm.exe を実行します。

    SimpleForm
    
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms




Public Class SimpleForm
   Inherits System.Windows.Forms.Form

   Private firstControl1 As FirstControl

   Private components As System.ComponentModel.Container = Nothing


   Public Sub New()
      InitializeComponent()
   End Sub 





   Private Sub InitializeComponent()
      Me.firstControl1 = New FirstControl()
      Me.SuspendLayout()

      ' 
      ' firstControl1
      ' 
      Me.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark
      Me.firstControl1.Location = New System.Drawing.Point(96, 104)
      Me.firstControl1.Name = "firstControl1"
      Me.firstControl1.Size = New System.Drawing.Size(75, 16)
      Me.firstControl1.TabIndex = 0
      Me.firstControl1.Text = "Hello World"
      Me.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter

      ' 
      ' SimpleForm
      ' 
      Me.ClientSize = New System.Drawing.Size(292, 266)
      Me.Controls.Add(firstControl1)
      Me.Name = "SimpleForm"
      Me.Text = "SimpleForm"
      Me.ResumeLayout(False)
   End Sub 


   <STAThread()>  _
   Shared Sub Main()
      Application.Run(New SimpleForm())
   End Sub 
End Class 
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace CustomWinControls
{

    public class SimpleForm : System.Windows.Forms.Form
    {
        private FirstControl firstControl1;

        private System.ComponentModel.Container components = null;

        public SimpleForm()
        {
            InitializeComponent();
        }

        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        private void InitializeComponent()
        {
            this.firstControl1 = new FirstControl();
            this.SuspendLayout();

            // 
            // firstControl1
            // 
            this.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark;
            this.firstControl1.Location = new System.Drawing.Point(96, 104);
            this.firstControl1.Name = "firstControl1";
            this.firstControl1.Size = new System.Drawing.Size(75, 16);
            this.firstControl1.TabIndex = 0;
            this.firstControl1.Text = "Hello World";
            this.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;

            // 
            // SimpleForm
            // 
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.Add(this.firstControl1);
            this.Name = "SimpleForm";
            this.Text = "SimpleForm";
            this.ResumeLayout(false);

        }

        [STAThread]
        static void Main() 
        {
            Application.Run(new SimpleForm());
        }


    }
}

参照

概念

Windows フォーム コントロールのイベント

その他の技術情報

Windows フォーム コントロールのプロパティ