Skip to content

Clarify user control consumer terminology and add minimum viable code explanation #2099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 25, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@ helpviewer_keywords:

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 <xref:System.Windows.Forms.TextBox> control with a <xref:System.Windows.Forms.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](usercontrol-overview.md).

## Understanding user control consumers

Throughout this article, the term **consumer** refers to any code that uses your user control. This includes:

- **Forms** that contain your user control.
- **Other controls** that host your user control.
- **Applications** that reference your user control library.

When you create a user control, you're building a reusable component. The consumer is whoever uses that component by placing it on a form, setting its properties, or responding to its events. The consumer doesn't need to know about the internal controls (like the `TextBox` and `Button`) that make up your user control—they only interact with the properties and events you choose to expose.

## Essential code pattern for user controls

Before adding the detailed implementation, it's helpful to understand the minimum viable code pattern for a user control. At its core, a user control needs:

- **Event forwarding** - Pass events from internal controls to the consumer.
- **Property exposure** - Allow the consumer to access internal control properties.
- **Logical behavior** - Handle interactions between internal controls.

The following code demonstrates these patterns. You don't need all of this code for a basic user control, but these patterns help create a professional, reusable component that integrates well with the designer and consumer applications.

## Add a new user control

After opening your Windows Forms project in Visual Studio, use the Visual Studio templates to create a user control:
Expand Down Expand Up @@ -91,27 +111,28 @@ The user control is made up of _constituent controls_, which are the controls yo
:::image type="content" source="./media/how-to-create-usercontrol/example-initial-design.png" alt-text="Visual Studio with Windows Forms, showing the user control that was just designed.":::

01. Press <kbd>F7</kbd> to open the code editor for the `ClearableTextBox` class.

01. Make the following code changes:

01. At the top of the code file, import the `System.ComponentModel` namespace.
01. 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#)](/dotnet/csharp/programming-guide/concepts/attributes/index) or [Attributes overview (Visual Basic)](/dotnet/visual-basic/programming-guide/concepts/attributes/index).
01. Add the `DefaultEvent` attribute to the class. This attribute sets which event is generated when the consumer (the form or application using this control) double-clicks the control in the designer. For more information about attributes, see [Attributes (C#)](/dotnet/csharp/programming-guide/concepts/attributes/index) or [Attributes overview (Visual Basic)](/dotnet/visual-basic/programming-guide/concepts/attributes/index).

:::code language="csharp" source="./snippets/how-to-create-usercontrol/csharp/ClearableTextBox.cs" id="default_event":::
:::code language="vb" source="./snippets/how-to-create-usercontrol/vb/ClearableTextBox.vb" id="default_event":::

01. Add an event handler that forwards the [`TextBox.TextChanged`](xref:System.Windows.Forms.Control.TextChanged) event to the consumer:
01. Add an event handler that forwards the [`TextBox.TextChanged`](xref:System.Windows.Forms.Control.TextChanged) event to consumers of your user control:

:::code language="csharp" source="./snippets/how-to-create-usercontrol/csharp/ClearableTextBox.cs" id="text_changed":::
:::code language="vb" source="./snippets/how-to-create-usercontrol/vb/ClearableTextBox.vb" id="text_changed":::

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.

01. Add a string property named `Text`, which forwards the [`TextBox.Text`](xref:System.Windows.Forms.Control.Text%2A) property to the consumer:
01. Add a string property named `Text`, which exposes the [`TextBox.Text`](xref:System.Windows.Forms.Control.Text%2A) property to consumers of your user control:

:::code language="csharp" source="./snippets/how-to-create-usercontrol/csharp/ClearableTextBox.cs" id="text":::
:::code language="vb" source="./snippets/how-to-create-usercontrol/vb/ClearableTextBox.vb" id="text":::

01. Add a string property named `Title`, which forwards the [`Label.Text`](xref:System.Windows.Forms.Label.Text%2A) property to the consumer:
01. Add a string property named `Title`, which exposes the [`Label.Text`](xref:System.Windows.Forms.Label.Text%2A) property to consumers of your user control:

:::code language="csharp" source="./snippets/how-to-create-usercontrol/csharp/ClearableTextBox.cs" id="title":::
:::code language="vb" source="./snippets/how-to-create-usercontrol/vb/ClearableTextBox.vb" id="title":::
Expand Down