ユーザー コントロールを作成する方法 (Windows Forms .NET)

この記事では、プロジェクトにユーザー コントロールを追加し、そのユーザー コントロールをフォームに追加する方法について説明します。 魅力的なビジュアルと機能を備え、再利用可能なユーザー コントロールを作成します。 新しいコントロールは、TextBox コントロールと Button コントロールをグループ分けします。 ユーザーがボタンを選択すると、テキスト ボックス内のテキストがクリアされます。 ユーザー コントロールの詳細については、「ユーザー コントロールの概要」を参照してください。

プロジェクトにユーザー コントロールを追加する

Visual Studio で Windows Forms プロジェクトを開いた後、Visual Studio テンプレートを使用して次のユーザー コントロールを作成します。

  1. Visual Studio で [プロジェクト エクスプローラー] ウィンドウを見つけます。 プロジェクトを右クリックして、[追加]>[ユーザー コントロール]\(Windows Forms) を選択します。

    Visual Studio ソリューション エクスプローラーを右クリックして、Windows Forms プロジェクトにユーザー コントロールを追加します

  2. コントロールの [名前][クリア可能]TextBox に設定し、[追加] を押します。

    Visual Studio for Windows Forms の [項目の追加] ダイアログ

ユーザー コントロールが作成されると、次のデザイナーによって Visual Studio が開きます。

Visual Studio for Windows Forms のユーザー コントロール デザイナー

クリア可能なテキスト ボックスを設計する

ユーザー コントロールは、フォームの設計方法と同様に、デザイン サーフェイスで作成するコントロールである内在コントロールで構成されます。 ユーザー コントロールとその内在コントロールを追加して構成するには、次の手順に従います。

  1. デザイナーを開いた状態で、ユーザー コントロールのデザイン サーフェイスを選択したオブジェクトにする必要があります。 そうでない場合は、デザイン サーフェスをクリックして選択します。 [プロパティ] ウィンドウで、次のプロパティを設定します。

    プロパティ
    MinimumSize 84, 53
    [サイズ] 191, 53
  2. Label コントロールを追加します。 次のようにプロパティを設定します。

    Property
    名前 lblTitle
    場所 3, 5
  3. TextBox コントロールを追加します。 次のようにプロパティを設定します。

    Property
    名前 txtValue
    アンカー Top, Left, Right
    場所 3, 23
    [サイズ] 148, 23
  4. Button コントロールを追加します。 次のようにプロパティを設定します。

    Property
    名前 btnClear
    アンカー Top, Right
    場所 157, 23
    サイズ 31, 23
    Text

    コントロールは次の画像のようになります。

    Visual Studio とデザインしたばかりのユーザー コントロールが表示されている Windows Forms。

  5. F7 キーを押して、ClearableTextBox クラスのコード エディターを開きます。

  6. 次のコード変更を行います。

    1. コード ファイルの先頭で System.ComponentModel 名前空間をインポートします。

    2. クラスに DefaultEvent 属性を追加します。 この属性では、デザイナーでコントロールをダブルクリックしたときにコンシューマーによって生成されるイベントが設定されます。 コンシューマーは、このコントロールを宣言して使用するオブジェクトのことです。 属性の詳細については、「属性 (C#)」または「属性の概要 (Visual Basic)」を参照してください。

      using System.ComponentModel;
      
      namespace UserControlProject
      {
          [DefaultEvent(nameof(TextChanged))]
          public partial class ClearableTextBox : UserControl
      
      Imports System.ComponentModel
      
      <DefaultEvent("TextChanged")>
      Public Class ClearableTextBox
      
    3. TextBox.TextChanged イベントを次のコンシューマーに転送するイベント ハンドラーを追加します。

      [Browsable(true)]
      public new event EventHandler? TextChanged
      {
          add => txtValue.TextChanged += value;
          remove => txtValue.TextChanged -= value;
      }
      
      <Browsable(True)>
      Public Shadows Custom Event TextChanged As EventHandler
          AddHandler(value As EventHandler)
              AddHandler txtValue.TextChanged, value
          End AddHandler
          RemoveHandler(value As EventHandler)
              RemoveHandler txtValue.TextChanged, value
          End RemoveHandler
          RaiseEvent(sender As Object, e As EventArgs)
      
          End RaiseEvent
      End Event
      

      イベントで Browsable 属性が宣言されていることに注意してください。 Browsable がイベントまたはプロパティに適用されている場合、デザイナーでコントロールを選択したときに、項目を [プロパティ] ウィンドウに表示するかどうかを制御します。 この場合、イベントを表示する必要があることを示す属性に true がパラメーターとして渡されます。

    4. Text という名前の文字列プロパティを追加します。これにより、TextBox.Text プロパティが次のコンシューマーに転送されます。

      [Browsable(true)]
      public new string Text
      {
          get => txtValue.Text;
          set => txtValue.Text = value;
      }
      
      <Browsable(True)>
      Public Shadows Property Text() As String
          Get
              Return txtValue.Text
          End Get
          Set(value As String)
              txtValue.Text = value
          End Set
      End Property
      
    5. Title という名前の文字列プロパティを追加します。これにより、Label.Text プロパティが次のコンシューマーに転送されます。

      [Browsable(true)]
      public string Title
      {
          get => lblTitle.Text;
          set => lblTitle.Text = value;
      }
      
      <Browsable(True)>
      Public Property Title() As String
          Get
              Return lblTitle.Text
          End Get
          Set(value As String)
              lblTitle.Text = value
          End Set
      End Property
      
  7. ClearableTextBox デザイナーに戻り、btnClear コントロールをダブルクリックして Click イベントのハンドラーを生成します。 ハンドラーに次のコードを追加します。これにより、次の txtValue テキスト ボックスがクリアされます。

    private void btnClear_Click(object sender, EventArgs e) =>
        Text = "";
    
    Private Sub btnClear_Click(sender As Object, e As EventArgs)
        txtValue.Text = ""
    End Sub
    
  8. 最後に、[ソリューション エクスプローラー] ウィンドウでプロジェクトを右クリックし、[ビルド] を選択してプロジェクトをビルドします。 エラーが発生しないようにし、ビルドが完了すると、ClearableTextBox コントロールがツールボックスに表示され、使用できるようになります。

次の手順では、フォームでコントロールを使用します。

サンプル アプリケーション

最後のセクションで新しいプロジェクトを作成した場合は、Form1 という名前の空白の Form が作成されます。それ以外の場合は、新しいフォームを作成します。

  1. [ソリューション エクスプローラー] ウィンドウで、フォームをダブルクリックして、デザイナーを開きます。 フォームのデザイン サーフェイスを選択する必要があります。

  2. Size プロパティを 432, 315 に設定します。

  3. [ツールボックス] ウィンドウを開き、[クリア可能]TextBox コントロールをダブルクリックします。 このコントロールは、プロジェクト後に名前が付けられたセクションの下に一覧表示されます。

  4. ここでも、[クリア可能]TextBox コントロールをダブルクリックして、2 つ目のコントロールを生成します。

  5. デザイナーに戻り、両方のコントロールを表示できるようにコントロールを分離します。

  6. コントロールを 1 つ選択し、次のプロパティを設定します。

    プロパティ
    名前 ctlFirstName
    場所 12, 12
    [サイズ] 191, 53
    Title First Name
  7. 他のコントロールを 1 つ選択し、次のプロパティを設定します。

    プロパティ
    名前 ctlLastName
    場所 12, 71
    [サイズ] 191, 53
    Title Last Name
  8. [ツールボックス] ウィンドウに戻り、フォームにラベル コントロールを追加し、次のプロパティを設定します。

    プロパティ
    名前 lblFullName
    場所 12, 252
  9. 次に、2 つのユーザー コントロールのイベント ハンドラーを生成する必要があります。 デザイナーで、ctlFirstName コントロールをダブルクリックします。 このアクションにより、TextChanged イベントのイベント ハンドラーが生成され、コード エディターが開きます。

  10. デザイナーに戻り、ctlLastName コントロールをダブルクリックして、2 番目のイベント ハンドラーを生成します。

  11. デザイナーに戻り、フォームのタイトル バーをダブルクリックします。 このアクションにより、Load イベントのイベント ハンドラーが生成されます。

  12. コード エディターで、UpdateNameLabel という名前のメソッドを追加します。 このメソッドは、両方の名前を組み合わせてメッセージを作成し、メッセージを lblFullName コントロールに割り当てます。

    private void UpdateNameLabel()
    {
        if (string.IsNullOrWhiteSpace(ctlFirstName.Text) || string.IsNullOrWhiteSpace(ctlLastName.Text))
            lblFullName.Text = "Please fill out both the first name and the last name.";
        else
            lblFullName.Text = $"Hello {ctlFirstName.Text} {ctlLastName.Text}, I hope you're having a good day.";
    }
    
    Private Sub UpdateNameLabel()
        If String.IsNullOrWhiteSpace(ctlFirstName.Text) Or String.IsNullOrWhiteSpace(ctlLastName.Text) Then
            lblFullName.Text = "Please fill out both the first name and the last name."
        Else
            lblFullName.Text = $"Hello {ctlFirstName.Text} {ctlLastName.Text}, I hope you're having a good day."
        End If
    End Sub
    
  13. どちらの TextChanged イベント ハンドラーも次の UpdateNameLabel メソッドを呼び出します。

    private void ctlFirstName_TextChanged(object sender, EventArgs e) =>
        UpdateNameLabel();
    
    private void ctlLastName_TextChanged(object sender, EventArgs e) =>
        UpdateNameLabel();
    
    Private Sub ctlFirstName_TextChanged(sender As Object, e As EventArgs) Handles ctlFirstName.TextChanged
        UpdateNameLabel()
    End Sub
    
    Private Sub ctlLastName_TextChanged(sender As Object, e As EventArgs) Handles ctlLastName.TextChanged
        UpdateNameLabel()
    End Sub
    
  14. 最後に、次のフォームの Load イベントから UpdateNameLabel メソッドを呼び出します。

    private void Form1_Load(object sender, EventArgs e) =>
        UpdateNameLabel();
    
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        UpdateNameLabel()
    End Sub
    

次のプロジェクトを実行し、姓と名を入力します。

ユーザー コントロールから作成された 2 つのテキスト ボックスとラベルが含まれた Windows Forms アプリ。

ボタンを押して、テキスト ボックスの 1 つをリセットしてみてください。