I'm trying to change the position of the icon in the textbox class with VB.NET
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.Right
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.Right
searchPictureBox.Size = New Size(16, 16)
searchPictureBox.TabIndex = 0
searchPictureBox.TabStop = False
Controls.Add(searchPictureBox)
' Send EM_SETMARGINS to prevent text from disappearing underneath the button
SendMessage(Handle, EM_SETMARGINS, New IntPtr(2), New IntPtr(16 << 16))
UpdateControlsVisibility()
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
<Browsable(True)>
Public Property SearchImage As Image
Set(ByVal value As Image)
searchPictureBox.Image = value
searchPictureBox.Left = Width - searchPictureBox.Size.Width - 4
searchPictureBox.Top = Height - searchPictureBox.Size.Height - 4
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
cancelSearchButton.Left = Width - searchPictureBox.Size.Width - 4
cancelSearchButton.Top = Height - searchPictureBox.Size.Height - 4
End Set
Get
Return cancelSearchButton.Image
End Get
End Property
End Class
result from code
Desired Result
Here is your code with the expected result.
Edit : I added an overide for OnSizeChanged in order to correctly position the icons when the size of the textbox changes
Imports System.ComponentModel
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 ReadOnly _IconPictureBox As PictureBox
Private _searchImage As Image
Private _cancelSearchImage As Image
Public Sub New()
_IconPictureBox = New PictureBox With {
.Anchor = AnchorStyles.Top Or AnchorStyles.Right,
.Size = New Size(Height - (Margin.Vertical + 2), Height - (Margin.Vertical + 2)),
.Top = Margin.Top,
.Left = Margin.Left,
.TabIndex = 0,
.TabStop = False,
.SizeMode = PictureBoxSizeMode.StretchImage
}
AddHandler _IconPictureBox.Click, Sub()
Text = ""
Focus()
End Sub
Controls.Add(_IconPictureBox)
' Send EM_SETMARGINS to prevent text from disappearing underneath the button
SendMessage(Handle, EM_SETMARGINS, New IntPtr(2), New IntPtr(16 << 16))
End Sub
Protected Overrides Sub OnTextChanged(ByVal e As EventArgs)
MyBase.OnTextChanged(e)
UpdateIcon()
End Sub
Protected Overrides Sub OnSizeChanged(ByVal e As EventArgs)
MyBase.OnSizeChanged(e)
UpdateIcon()
End Sub
Private Sub UpdateIcon()
If String.IsNullOrEmpty(Text) Then
_IconPictureBox.Image = _searchImage
_IconPictureBox.Left = Margin.Left
Else
_IconPictureBox.Image = _cancelSearchImage
_IconPictureBox.Cursor = Cursors.Arrow
_IconPictureBox.Left = Width - _IconPictureBox.Size.Width - Margin.Horizontal
End If
End Sub
<Browsable(True)>
Public Property SearchImage As Image
Set(value As Image)
_searchImage = value
UpdateIcon()
End Set
Get
Return _searchImage
End Get
End Property
<Browsable(True)>
Public Property CancelSearchImage As Image
Set(value As Image)
_cancelSearchImage = value
UpdateIcon()
End Set
Get
Return _cancelSearchImage
End Get
End Property
End Class
Here is the result :
If necessary, here are the images I used :