WinForms
TextBox
Button Integration
C# Windows Forms
UI Development

Button inside a WinForms textbox

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

WinForms does not have a built-in TextBox with an embedded button like many modern search fields. If you want a clear button, browse button, or password-toggle button inside the text area, the practical solution is to build a small composite control.

The core idea is simple: host a borderless TextBox and a narrow Button inside a parent control that draws the outer border. That keeps the behavior predictable and works better than trying to paint a clickable button directly inside a standard TextBox.

Why a Composite Control Is the Usual Solution

A standard WinForms TextBox is a wrapped native control. It does not expose a supported API for placing child controls inside its client area. You can fake the appearance with custom painting, but handling focus, clicks, resizing, keyboard navigation, and DPI scaling becomes brittle.

A UserControl or custom Control is more maintainable because you control the layout yourself.

A Minimal Working Example

The following custom control places a borderless TextBox and a button side by side inside a reusable UserControl.

csharp
1using System;
2using System.Drawing;
3using System.Windows.Forms;
4
5public class TextBoxWithButton : UserControl
6{
7    private readonly TextBox _textBox;
8    private readonly Button _button;
9
10    public TextBoxWithButton()
11    {
12        Height = 24;
13        BackColor = SystemColors.Window;
14        Padding = new Padding(1);
15
16        _textBox = new TextBox
17        {
18            BorderStyle = BorderStyle.None,
19            Location = new Point(6, 5),
20            Width = Width - 32,
21            Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top
22        };
23
24        _button = new Button
25        {
26            Text = "...",
27            Width = 26,
28            Dock = DockStyle.Right,
29            TabStop = false
30        };
31
32        _button.Click += (_, __) => ButtonClicked?.Invoke(this, EventArgs.Empty);
33
34        Controls.Add(_textBox);
35        Controls.Add(_button);
36        Resize += (_, __) => _textBox.Width = Width - _button.Width - 10;
37    }
38
39    public string TextValue
40    {
41        get => _textBox.Text;
42        set => _textBox.Text = value;
43    }
44
45    public string ButtonText
46    {
47        get => _button.Text;
48        set => _button.Text = value;
49    }
50
51    public event EventHandler? ButtonClicked;
52
53    protected override void OnPaint(PaintEventArgs e)
54    {
55        base.OnPaint(e);
56        ControlPaint.DrawBorder(e.Graphics, ClientRectangle, SystemColors.ControlDark, ButtonBorderStyle.Solid);
57    }
58}

Use it from a form like this:

csharp
1using System;
2using System.Windows.Forms;
3
4public class MainForm : Form
5{
6    public MainForm()
7    {
8        var search = new TextBoxWithButton
9        {
10            Dock = DockStyle.Top,
11            ButtonText = "Go"
12        };
13
14        search.ButtonClicked += (_, __) => MessageBox.Show($"Searching for: {search.TextValue}");
15        Controls.Add(search);
16    }
17
18    [STAThread]
19    public static void Main()
20    {
21        Application.EnableVisualStyles();
22        Application.Run(new MainForm());
23    }
24}

This gives you a reusable control with normal WinForms event handling and predictable layout.

Design Choices That Matter

A borderless inner TextBox is the trick that makes the control look like one unified field. The outer control draws the border, so the text area and the button appear visually integrated.

You should also decide whether the button belongs in the tab order. For a search box, many developers keep the button reachable by mouse only and trigger the action on Enter from the text box. For accessibility-focused workflows, keeping the button tabbable may be better.

If the button is meant to clear the text, you can wire it directly:

csharp
search.ButtonClicked += (_, __) => search.TextValue = string.Empty;

For password reveal, you would toggle the inner text box behavior instead of launching a separate action.

Alternatives

You can also use a Panel containing a TextBox and Button without creating a custom class. That is fine for one form, but a dedicated control is better if you need the same pattern more than once.

Another option is subclassing and heavy custom painting, but that is usually more work than the problem deserves in WinForms.

Common Pitfalls

The most common mistake is trying to add a real Button as a child of a standard TextBox. Native text boxes are not designed for that, and the result usually breaks on resize or focus changes.

Another mistake is forgetting DPI and font scaling. Hard-coded positions that look correct at one scaling level can drift badly on another monitor.

Developers also forget to expose the inner text box properties they actually need, such as Text, ReadOnly, or UseSystemPasswordChar. If the composite control is meant to be reused, surface the important properties cleanly.

Finally, watch keyboard behavior. If pressing Enter should activate the embedded button, handle the text box key event intentionally instead of assuming the form’s default button will do the right thing.

Summary

  • A standard WinForms TextBox does not support a true embedded button by itself.
  • The maintainable solution is a composite control containing a borderless TextBox and a Button.
  • Drawing the outer border on the parent control makes the field look like one integrated widget.
  • Expose only the inner properties and events you actually need for reuse.
  • Pay attention to resizing, keyboard behavior, and DPI scaling so the control stays usable in real forms.

Course illustration
Course illustration

All Rights Reserved.