2

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?

Community
  • 1
  • 1
Tadumc421
  • 149
  • 2
  • 4
  • 12
  • 1
    I think what you are after is a Cue Banner, provided by Win32 API. See here for details: https://stackoverflow.com/questions/4902565/watermark-textbox-in-winforms – JayV Jun 19 '18 at 09:32
  • @Tadumc421 You should not put the answer as part of the question. It makes the question confusing and the answers nonsense. The check-mark near the answer is for showing what answer you have accepted. If for any reason you see a point in saying which of the solutions of the accepted answer was more useful for you, you can put it as a comment under the question or under that answer :) – Reza Aghaei Jun 19 '18 at 14:05
  • My bad, I will remove it. I am somewhat new to stackoverflow so bear with me. Edit: ty, you did it for me xD – Tadumc421 Jun 19 '18 at 14:10

3 Answers3

4

.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
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
0

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

esmehsnj
  • 162
  • 2
  • 17
  • I've implemented the code into my program, but it does not work as intended. Screenshot: https://imgur.com/a/ymQCKdW OnSelect i want this text to be gone, but in the code you have provided me with, it doesn't do what i was looking for. Maybe you have any suggestions how to fix something like this? – Tadumc421 Jun 19 '18 at 09:40
  • @E.Hysenaj Most welcome – Mayur Prajapati Jun 19 '18 at 10:16
  • 1
    @Tadumc421 take a look at the edited version – esmehsnj Jun 19 '18 at 10:25
  • @E.Hysenaj Okay, i have configured the code as you sugested and it works. But i have a problem. What if my users name is: 'User Name'? Is there a way if we change the default text to the same text so it can be accepted? Let me know if you don't understand the question i just asked. – Tadumc421 Jun 19 '18 at 10:28
  • 1
    @Tadumc421 what do you mean with "What if my users name is: 'User Name'?" are you talking about the place holder text, Do you want to change it? – esmehsnj Jun 19 '18 at 10:35
  • If my users username is "User Name" and he enters the "User Name" in the textbox, when we Leave the textbox, and then Enter it again, the text they just entered ("User Name") dissapears. Here is the example: https://imgur.com/a/bST00Q4 – Tadumc421 Jun 19 '18 at 10:38
  • @Tadumc421 right, nice case but will there actually be any case where the user's username is "User Name"? – esmehsnj Jun 19 '18 at 10:44
  • I am not creating this option only for Username and Password but for many others that may contain the same words as the placeholder suggests. – Tadumc421 Jun 19 '18 at 10:51
  • Anyways @E.Hysenaj i got the answer to my original question from other dude. Ty anyways for your help! – Tadumc421 Jun 19 '18 at 11:02
  • 1
    @Tadumc421 I'm glad you found the right answer :) – esmehsnj Jun 19 '18 at 11:12
  • @E.Hysenaj Assigning the watermark value to `Text` property of the `TextBox` is bad idea and dangrous. It may raise validation errors, it may go to the data source when using data-binding, it may be saved in data store. The correct approach is sending `EM_SETCUEBANNER` or handling `WM_PAINT` as I described in the answer. – Reza Aghaei Jun 19 '18 at 14:20
0

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!

Ste Griffiths
  • 318
  • 5
  • 15
  • Will this type of code work in VB.NET since im not familiar with '{' and '}' in VB.NET environment? – Tadumc421 Jun 19 '18 at 09:53
  • Assigning the watermark value to `Text` property of the `TextBox` is bad idea and dangerous. It may raise validation errors, it may go to the data source when using data-binding, it may be saved in data store. The correct approach is sending `EM_SETCUEBANNER` or handling `WM_PAINT` as I described in the answer. – Reza Aghaei Jun 19 '18 at 14:17