共用方式為


如何建立使用者控制項

本文將教導您如何將使用者控件新增至專案,然後將該使用者控件新增至表單。 您將建立既具有視覺吸引力又能運作,且可重複使用的使用者控制項。 新的控制群組將 TextBox 控制項與 Button 控制項組成群組。 當使用者選取按鈕時,文字方塊中的文字會被清除。 若要了解更多使用者控制項的資訊,請參閱使用者控制項概觀

了解使用者控制的消費者

在本文中,「使用者」一詞是指任何使用您使用者控制項的程式代碼。 這包括:

  • 包含使用者控制件的表單
  • 裝載使用者控制件的其他控制件
  • 應用程式參考您的使用者控制項庫。

當您建立使用者控制項時,您要建置可重複使用的元件。 使用者是指通過將該元件放置在窗體上、設定其屬性或回應其事件來使用該元件的人。 取用者不需要知道組成使用者控件的內部控制項(例如 TextBoxButton),它們只會與您選擇公開的屬性和事件互動。

使用者控制項的基本程式代碼模式

在新增詳細實作之前,了解使用者控制項的最小可行程式碼範本是有幫助的。 使用者控制項在核心上需要:

  • 事件轉送 - 將事件從內部控件傳遞至取用者。
  • 屬性曝光 - 允許取用者存取內部控制屬性。
  • 邏輯行為 - 處理內部控制件之間的互動。

下列程式代碼示範這些模式。 您不需要基本使用者介面控制項的所有此程式碼,但這些模式有助於建立專業且可重覆使用的元件,與設計者工具和使用者應用程式整合良好。

新增使用者控制件

在 Visual Studio 中開啟 Windows Forms 專案之後,請使用 Visual Studio 範本來建立使用者控制項:

  1. 在 Visual Studio 中,尋找 [方案總管 ] 視窗。 以滑鼠右鍵按兩下專案,然後選擇 [新增]>[使用者控制項 (Windows Forms)]

    以滑鼠右鍵按一下 Visual Studio 方案總管,以將使用者控制項新增至 Windows Forms 專案

  2. 將控制項的 [名稱] 設定為 [ClearableTextBox],然後按下 [新增]

    Visual Studio 中的 [新增項目] 對話方塊 (適用於 Windows Forms)

建立使用者控制項之後,Visual Studio 會開啟設計工具:

Visual Studio 中的使用者控制項設計工具 (適用於 Windows Forms)

設計可清除的文字輸入框

使用者控件是由 組成控件所組成,,這是您在設計介面上 建立的控件,就像您設計表單的方式一樣。 請遵循下列步驟來新增及設定使用者控制項及其組成控制項:

  1. 當設計工具開啟時,使用者控制的設計介面應該是被選取的物件。 如果不是,請按一下設計畫面以加以選取。 在 [屬性] 視窗中設定下列屬性:

    房產 價值觀
    最小尺寸 84, 53
    大小 191, 53
  2. 新增 Label 控制項。 設定下列屬性:

    房產 價值觀
    名稱 lblTitle
    地點 3, 5
  3. 新增 TextBox 控制項。 設定下列屬性:

    房產 價值觀
    名稱 txtValue
    錨點 Top, Left, Right
    地點 3, 23
    大小 148, 23
  4. 新增 Button 控制項。 設定下列屬性:

    房產 價值觀
    名稱 btnClear
    錨點 Top, Right
    地點 157, 23
    大小 31, 23
    文字

    控制項看起來應該像下列影像:

    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)]
      [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
      public new string Text
      {
          get => txtValue.Text;
          set => txtValue.Text = value;
      }
      
      <Browsable(True)>
      <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
      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)]
      [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
      public string Title
      {
          get => lblTitle.Text;
          set => lblTitle.Text = value;
      }
      
      <Browsable(True)>
      <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
      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 控制項會出現在工具箱中以供使用。

下一個步驟是使用表單中的控件。

範例應用程式

如果您在上一節中建立了新專案,那您會有一個名為 Form的空白 ,否則請建立新的表單。

  1. 在 [方案總管] 視窗中,按兩下表單以開啟設計工具。 應該選取表單的設計區域。

  2. 將表單的 Size 屬性設定為 432, 315

  3. 開啟 [工具箱] 視窗,然後按兩下 [ClearableTextBox] 控制項。 此控制項應該列在以專案名稱命名的區段底下。

  4. 再次按兩下 [ClearableTextBox] 控制項,以產生第二個控制項。

  5. 返回設計工具,並分開控制項,以便您可以看到兩個控制項。

  6. 選取一個控制項並設定下列屬性:

    房產 價值觀
    名稱 ctlFirstName
    地點 12, 12
    大小 191, 53
    標題 First Name
  7. 選取另一個控制項並設定下列屬性:

    房產 價值觀
    名稱 ctlLastName
    地點 12, 71
    大小 191, 53
    標題 Last Name
  8. 回到 [工具箱] 視窗中,將標籤新增至表單,並設定下列屬性:

    房產 價值觀
    名稱 lblFullName
    地點 12, 252
  9. 接下來,您必須為兩個使用者控制項產生事件處理常式。 在設計工具中,按兩下 ctlFirstName 控制項。 此動作會為 TextChanged 事件產生事件處理常式,並開啟程式碼編輯器。

  10. 切換回設計工具,然後按兩下 ctlLastName 控制項以產生第二個事件處理常式。

  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. 最後,從表單的 UpdateNameLabel 事件中呼叫 Load 方法:

    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
    

執行專案並輸入名稱與姓氏:

Windows Forms 應用程式,其中包含從使用者控件和標籤建立的兩個文字框。

請嘗試按下 [] 按鈕來重設其中一個文字框。