You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

关键修改点说明:

  1. 控件锚定方式:将AnchorStyles.Top Or AnchorStyles.Right改为AnchorStyles.Top Or AnchorStyles.Left,确保文本框大小变化时控件始终贴靠左侧。
  2. 内边距设置:修改SendMessage的参数,wp设为1表示设置左内边距,lp设为16 + 4(控件宽度+偏移量),避免输入的文本覆盖左侧图标。
  3. 控件位置计算:去掉原代码中基于右侧的位置计算,改为左侧固定偏移4像素,同时垂直居中控件(使用(Height - Size.Height) \ 2),视觉效果更协调。
  4. 新增位置更新逻辑:添加UpdateControlsPosition方法统一处理控件定位,并重写OnResize方法,确保文本框大小变化时控件位置自动修正。

效果对比

当前代码运行效果:
当前效果

期望效果(修改后可实现):
期望效果

内容的提问来源于stack exchange,提问作者roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:05:58