如何在VB.NET自定义TextBox类中调整图标至左侧位置
VB.NET自定义SearchTextBox:将图标移至左侧的修改方案
要把搜索图标和清除按钮从文本框右侧移到左侧,需要对原代码的控件锚定、内边距设置、控件定位逻辑进行调整,以下是修改后的完整代码:
Public Class SearchTextBox Inherits TextBox Private Const EM_SETMARGINS As Integer = &Hd3 <System.Runtime.InteropServices.DllImport("user32.dll")> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wp As IntPtr, ByVal lp As IntPtr) As IntPtr End Function Private searchPictureBox As PictureBox Private cancelSearchButton As Button Public Sub New() cancelSearchButton = New Button() ' 修改锚定方式为左上,确保文本框大小变化时控件保持在左侧 cancelSearchButton.Anchor = AnchorStyles.Top Or AnchorStyles.Left cancelSearchButton.Size = New Size(16, 16) cancelSearchButton.TabIndex = 0 cancelSearchButton.TabStop = False cancelSearchButton.FlatStyle = FlatStyle.Flat cancelSearchButton.FlatAppearance.BorderSize = 0 cancelSearchButton.Text = "" cancelSearchButton.Cursor = Cursors.Arrow Controls.Add(cancelSearchButton) AddHandler cancelSearchButton.Click, Sub() Text = "" Focus() End Sub searchPictureBox = New PictureBox() ' 修改锚定方式为左上 searchPictureBox.Anchor = AnchorStyles.Top Or AnchorStyles.Left searchPictureBox.Size = New Size(16, 16) searchPictureBox.TabIndex = 0 searchPictureBox.TabStop = False Controls.Add(searchPictureBox) ' 发送EM_SETMARGINS设置左内边距,防止文本覆盖左侧控件 ' wp参数为1表示设置左内边距,lp参数的低16位表示左内边距宽度 SendMessage(Handle, EM_SETMARGINS, New IntPtr(1), New IntPtr(16 + 4)) UpdateControlsVisibility() ' 初始化控件位置 UpdateControlsPosition() End Sub ' 重写OnResize方法,文本框大小变化时重新定位控件 Protected Overrides Sub OnResize(e As EventArgs) MyBase.OnResize(e) UpdateControlsPosition() End Sub Protected Overrides Sub OnTextChanged(ByVal e As EventArgs) MyBase.OnTextChanged(e) UpdateControlsVisibility() End Sub Private Sub UpdateControlsVisibility() If String.IsNullOrEmpty(Text) Then cancelSearchButton.Visible = False searchPictureBox.Visible = True Else cancelSearchButton.Visible = True searchPictureBox.Visible = False End If End Sub ' 新增方法统一处理控件位置 Private Sub UpdateControlsPosition() ' 左侧偏移4像素,垂直居中 searchPictureBox.Left = 4 searchPictureBox.Top = (Height - searchPictureBox.Size.Height) \ 2 cancelSearchButton.Left = 4 cancelSearchButton.Top = (Height - cancelSearchButton.Size.Height) \ 2 End Sub <Browsable(True)> Public Property SearchImage As Image Set(ByVal value As Image) searchPictureBox.Image = value ' 重新定位控件 UpdateControlsPosition() End Set Get Return searchPictureBox.Image End Get End Property <Browsable(True)> Public Property CancelSearchImage As Image Set(ByVal value As Image) cancelSearchButton.Image = value ' 重新定位控件 UpdateControlsPosition() End Set Get Return cancelSearchButton.Image End Get End Property End Class
关键修改点说明:
- 控件锚定方式:将
AnchorStyles.Top Or AnchorStyles.Right改为AnchorStyles.Top Or AnchorStyles.Left,确保文本框大小变化时控件始终贴靠左侧。 - 内边距设置:修改
SendMessage的参数,wp设为1表示设置左内边距,lp设为16 + 4(控件宽度+偏移量),避免输入的文本覆盖左侧图标。 - 控件位置计算:去掉原代码中基于右侧的位置计算,改为左侧固定偏移4像素,同时垂直居中控件(使用
(Height - Size.Height) \ 2),视觉效果更协调。 - 新增位置更新逻辑:添加
UpdateControlsPosition方法统一处理控件定位,并重写OnResize方法,确保文本框大小变化时控件位置自动修正。
效果对比
当前代码运行效果:
期望效果(修改后可实现):
内容的提问来源于stack exchange,提问作者roy
相关产品推荐
相关产品推荐

