如何在WinForms中创建带图标和清除按钮的搜索框?
解决WinForms仿Windows 11任务管理器搜索框的两个问题
一、解决按钮覆盖文本框导致文本输入到按钮下方的问题
核心是让文本框的输入区域避开按钮位置,提供两种可行方案:
调整文本框Padding
根据左侧图标按钮和右侧清除按钮的宽度,直接设置文本框的Padding属性,让输入区域自动避开按钮:// 假设txtSearch是文本框,btnLeftIcon是左侧图标按钮,btnClear是右侧清除按钮 txtSearch.Padding = new Padding(btnLeftIcon.Width + 4, txtSearch.Padding.Top, btnClear.Width + 4, txtSearch.Padding.Bottom);额外的4px是为了保留图标/按钮和文本之间的间距,避免过于拥挤。
自定义文本框输入区域
如果需要更精确的控制,可继承TextBox重写输入区域:public class RestrictedInputTextBox : TextBox { private Rectangle _inputBounds; public Rectangle InputBounds { get => _inputBounds; set { _inputBounds = value; UpdateInputArea(); } } private void UpdateInputArea() { if (IsHandleCreated) SendMessage(Handle, 0xB3, IntPtr.Zero, ref _inputBounds); } [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, ref Rectangle lp); protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); UpdateInputArea(); } }使用时根据按钮位置设置
InputBounds,就能严格限定文本输入的范围。
二、解决焦点栏无法铺满整个控件的问题
用面板组合后,焦点仅作用于文本框,导致焦点栏只显示文本框范围。可以通过自定义复合控件统一处理焦点视觉效果:
创建自定义搜索控件
继承UserControl,内部包含文本框、图标按钮和清除按钮,隐藏文本框原生边框,统一绘制焦点样式:
public class Win11SearchBox : UserControl { private readonly TextBox _searchTextBox; private readonly Button _iconButton; private readonly Button _clearButton; public Win11SearchBox() { SetStyle(ControlStyles.Selectable, true); TabStop = true; BorderStyle = BorderStyle.FixedSingle; Size = new Size(220, 28); // 初始化图标按钮 _iconButton = new Button { Dock = DockStyle.Left, Width = 24, FlatStyle = FlatStyle.Flat, FlatAppearance = { BorderSize = 0 }, BackgroundImage = Properties.Resources.SearchIcon // 替换为你的搜索图标 }; // 初始化清除按钮 _clearButton = new Button { Dock = DockStyle.Right, Width = 24, FlatStyle = FlatStyle.Flat, FlatAppearance = { BorderSize = 0 }, BackgroundImage = Properties.Resources.ClearIcon, // 替换为你的清除图标 Visible = false }; _clearButton.Click += (s, e) => { _searchTextBox.Text = ""; _searchTextBox.Focus(); }; // 初始化文本框 _searchTextBox = new TextBox { Dock = DockStyle.Fill, BorderStyle = BorderStyle.None, Padding = new Padding(4, 0, 4, 0) }; _searchTextBox.TextChanged += (s, e) => _clearButton.Visible = !string.IsNullOrEmpty(_searchTextBox.Text); Controls.Add(_searchTextBox); Controls.Add(_iconButton); Controls.Add(_clearButton); } protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); _searchTextBox.Focus(); Invalidate(); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ContainsFocus) { // 绘制Win11风格的蓝色焦点边框 using var focusPen = new Pen(Color.FromArgb(0, 120, 215), 2); e.Graphics.DrawRectangle(focusPen, new Rectangle(0, 0, Width - 1, Height - 1)); } } }
效果说明
- 文本框隐藏原生边框,避免局部焦点栏
- 控件获得焦点时,绘制覆盖整个控件的蓝色边框,和原生文本框焦点效果一致
- 清除按钮会根据文本内容自动显示/隐藏
内容的提问来源于stack exchange,提问作者Sam Axe
相关产品推荐
相关产品推荐

