.NET 5.0+ or .NET Core 3.0+
Use TextBox.PlaceholderText property:
textBox1.PlaceholderText = "Enter your name"
.NET Framework
You can use either of the following approaches:
Sending EM_SETCUEBANNER
to use the built-in placeholder feature of TextBox (Which just supports single-line text with gray placeholder text)
Handling WM_PAINT message to show placeholder with custom color on both multi-line and single line TextBox (Which is the way that later is implemented in .NET Core)
Using EM_SETCUEBANNER
You can find a C# implementation of this approach here in this
post.
By sending EM_SETCUEBANNER
to a TextBox
, you can set the textual cue, or tip, that is displayed by the edit control to prompt the user for information.
Imports System
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Public Class MyTextBox
Inherits TextBox
Private Const EM_SETCUEBANNER As Integer = &H1501
<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, _
ByVal wParam As Integer, ByVal lParam As String) As Int32
End Function
Protected Overrides Sub OnHandleCreated(e As EventArgs)
MyBase.OnHandleCreated(e)
If Not String.IsNullOrEmpty(CueBanner) Then UpdateCueBanner()
End Sub
Private m_CueBanner As String
Public Property CueBanner As String
Get
Return m_CueBanner
End Get
Set(ByVal value As String)
m_CueBanner = value
UpdateCueBanner()
End Set
End Property
Private Sub UpdateCueBanner()
SendMessage(Me.Handle, EM_SETCUEBANNER, 0, CueBanner)
End Sub
End Class
Handling WM_PAINT
You can find a C# implementation of this approach here in this
post.
If you use EM_SETCUEBANNER, the hint always will be shown in a system default color. Also the hint will not be shown when the TextBox is MultiLine.
Using the painting solution, you can show the text with any color that you want. You also can show the watermark when the control is multi-line
Imports System.Drawing
Imports System.Windows.Forms
Public Class ExTextBox
Inherits TextBox
Private m_Hint As String
Public Property Hint As String
Get
Return m_Hint
End Get
Set(ByVal value As String)
m_Hint = value
Me.Invalidate()
End Set
End Property
Protected Overrides Sub WndProc(ByRef m As Message)
MyBase.WndProc(m)
If m.Msg = &HF Then
If Not Me.Focused AndAlso String.IsNullOrEmpty(Me.Text) _
AndAlso Not String.IsNullOrEmpty(Me.Hint) Then
Using g = Me.CreateGraphics()
TextRenderer.DrawText(g, Me.Hint, Me.Font, Me.ClientRectangle, _
SystemColors.GrayText, Me.BackColor, _
TextFormatFlags.Top Or TextFormatFlags.Left)
End Using
End If
End If
End Sub
End Class