'Placeholder in TextBox in Window Forms using VB.NET

I'm working on a Windows Forms application in VB.NET and I am currently making a login screen using labels and TextBoxes.

What I need is the Placeholder in TextBox controls you can see below ↓ (not mine obviously)

Prototype image taken from google pictures

Is there any property in TextBox that allows me to set the default placeholder (placeholder, watermark, hint, tip) to what I want it to be? If there is not any, how can i solve this differently?



Solution 1:[1]

.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

Solution 2:[2]

This feature is not built in. However, you can create a control which inherits from TextBox and use these on your form. Here is one I made earlier: Placeholder textbox

The key features are the following. Have a property for Placeholder text and a bool property which calculates whether or not to show it:

public string Placeholder { get; set; }
public bool HasUserContent
{
    get
    {
        return (!string.IsNullOrEmpty(Text) && Text != Placeholder);
    }
}

During instantiation, set event handlers on focus and blur:

GotFocus += PlaceholderTextbox_GotFocus;
LostFocus += PlaceholderTextbox_LostFocus;

And implement those events to switch between gray placeholder text and black user text:

private void PlaceholderTextbox_LostFocus(object sender, EventArgs e)
{
    if (Text == string.Empty)
    {
        Text = Placeholder;
        ForeColor = SystemColors.GrayText;
    }
}

private void PlaceholderTextbox_GotFocus(object sender, EventArgs e)
{
    if (Text == Placeholder)
    {
        Text = string.Empty;
        ForeColor = SystemColors.ControlText;
    }
}

More detail is in the file I linked above. Hope this helps!

Solution 3:[3]

Give it a try to the answer given here

EDIT: I am editing the answer with adding code and specifications

Use the code below, and only replace the names of the text boxes and the text you want to display as placeholder, respectively as you have them in your code, i have named them TextBox1 and "User Name" => for the user name texbox and TextBox2 and "Password" => for the password textbox and make sure you change them

Private Sub TextBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles TextBox1.Enter, TextBox2.Enter

    Dim tb As TextBox = DirectCast(sender, TextBox)

    With tb
        .ForeColor = Color.Black
        .Font = New Font("Microsoft Sans Serif", 8, FontStyle.Regular)

        Select Case tb.Name
            Case "TextBox1"
                If .Text = "User Name" Then
                    .Clear()
                End If

            Case "TextBox2"
                If .Text = "Password" Then
                    .Clear()
                End If
        End Select
    End With

End Sub

Private Sub TextBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles TextBox1.Leave, TextBox2.Leave

    Dim tb As TextBox = DirectCast(sender, TextBox)

    If tb.Text.Trim = "" Then
        Select Case tb.Name
            Case "TextBox1"
                SetUserToDefault()

            Case "TextBox2"
                SetPasswordToDefault()
        End Select
    End If

End Sub

Private Sub SetUserToDefault()

    With TextBox1
        .ForeColor = Color.Gray
        .Font = New Font("Arial", 10, FontStyle.Italic)
        .Text = "User Name"
        .TabStop = False
    End With

End Sub

Private Sub SetPasswordToDefault()

    With TextBox2
        .ForeColor = Color.Gray
        .Font = New Font("Arial", 10, FontStyle.Italic)
        .Text = "Password"
        .TabStop = False
    End With
End Sub

I compiled and tried the code and it works, so if it still won't work, provide you example here.

Regards

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Ste Griffiths
Solution 3