How to create a user control (Windows Forms .NET)

This article teaches you how to add a user control to your project and then add that user control to a form. You'll create a reusable user control that's both visually appealing and functional. The new control groups a TextBox control with a Button control. When the user selects the button, the text in the text box is cleared. For more information about user controls, see User control overview.

Add a user control to a project

After opening your Windows Forms project in Visual Studio, use the Visual Studio templates to create a user control:

  1. In Visual Studio, find the Project Explorer window. Right-click on the project and choose Add > User Control (Windows Forms).

    Right-click the Visual Studio solution explorer to add a user control to a Windows Forms project

  2. Set the Name of the control to ClearableTextBox, and press Add.

    Add item dialog in Visual Studio for Windows Forms

After the user control is created, Visual Studio opens the designer:

The user control designer in Visual Studio for Windows Forms

Design the clearable text box

The user control is made up of constituent controls, which are the controls you create on the design surface, just like how you design a form. Follow these steps to add and configure the user control and its constituent controls:

  1. With the designer open, the user control design surface should be the selected object. If it's not, click on the design surface to select it. Set the following properties in the Properties window:

    Property Value
    MinimumSize 84, 53
    Size 191, 53
  2. Add a Label control. Set the following properties:

    Property Value
    Name lblTitle
    Location 3, 5
  3. Add a TextBox control. Set the following properties:

    Property Value
    Name txtValue
    Anchor Top, Left, Right
    Location 3, 23
    Size 148, 23
  4. Add a Button control. Set the following properties:

    Property Value
    Name btnClear
    Anchor Top, Right
    Location 157, 23
    Size 31, 23
    Text

    The control should look like the following image:

    Visual Studio with Windows Forms, showing the user control that was just designed.

  5. Press F7 to open the code editor for the ClearableTextBox class.

  6. Make the following code changes:

    1. At the top of the code file, import the System.ComponentModel namespace.

    2. Add the DefaultEvent attribute to the class. This attribute sets which event is generated by the consumer when the control is double-clicked in the designer. The consumer being the object declaring and using this control. For more information about attributes, see Attributes (C#) or Attributes overview (Visual Basic).

      using System.ComponentModel;
      
      namespace UserControlProject
      {
          [DefaultEvent(nameof(TextChanged))]
          public partial class ClearableTextBox : UserControl
      
      Imports System.ComponentModel
      
      <DefaultEvent("TextChanged")>
      Public Class ClearableTextBox
      
    3. Add an event handler that forwards the TextBox.TextChanged event to the consumer:

      [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
      

      Notice that the event has the Browsable attribute declared on it. When the Browsable is applied to an event or property, it controls whether or not the item is visible in the Properties window when the control is selected in the designer. In this case, true is passed as a parameter to the attribute indicating that the event should be visible.

    4. Add a string property named Text, which forwards the TextBox.Text property to the consumer:

      [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. Add a string property named Title, which forwards the Label.Text property to the consumer:

      [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. Switch back to the ClearableTextBox designer and double-click the btnClear control to generate a handler for the Click event. Add the following code for the handler, which clears the txtValue text box:

    private void btnClear_Click(object sender, EventArgs e) =>
        Text = "";
    
    Private Sub btnClear_Click(sender As Object, e As EventArgs)
        txtValue.Text = ""
    End Sub
    
  8. Finally, build the project by right-clicking the project in the Solution Explorer window, and selecting Build. There shouldn't be any errors, and after the build is finished, the ClearableTextBox control appears in the toolbox for use.

The next step is using the control in a form.

Sample application

If you created a new project in the last section, you have a blank Form named Form1, otherwise, create a new form.

  1. In the Solution Explorer window, double-click the form to open the designer. The form's design surface should be selected.

  2. Set the form's Size property to 432, 315.

  3. Open the Toolbox window, and double-click the ClearableTextBox control. This control should be listed under a section named after your project.

  4. Again, double-click on the ClearableTextBox control to generate a second control.

  5. Move back to the designer and separate the controls so that you can see both of them.

  6. Select one control and set the following properties:

    Property Value
    Name ctlFirstName
    Location 12, 12
    Size 191, 53
    Title First Name
  7. Select the other control and set the following properties:

    Property Value
    Name ctlLastName
    Location 12, 71
    Size 191, 53
    Title Last Name
  8. Back in the Toolbox window, add a label control to the form, and set the following properties:

    Property Value
    Name lblFullName
    Location 12, 252
  9. Next, you need to generate the event handlers for the two user controls. In the designer, double-click on the ctlFirstName control. This action generates the event handler for the TextChanged event, and opens the code editor.

  10. Swap back to the designer and double-click the ctlLastName control to generate the second event handler.

  11. Swap back to the designer and double-click on the form's title bar. This action generates an event handler for the Load event.

  12. In the code editor, add a method named UpdateNameLabel. This method combines both names to create a message, and assigns the message to the lblFullName control.

    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. For both TextChanged event handlers, call the UpdateNameLabel method:

    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. Finally, call the UpdateNameLabel method from the form's Load event:

    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
    

Run the project and enter a first and last name:

A Windows Forms app with two text boxes created from user controls, and a label.

Try pressing the button to reset one of the text boxes.