0

I'm making a custom textbox (im new at this) with a watermark that uses a embbeded custom font but I can not make it work properly. textbox faliure

these are the problems:

  1. When I'm typing, the cursor seems to go behind the text
  2. When I click inside the textbox or when I select the text from the textbox, the text appears without the custom font
  3. When the mouse leaves the control after having clicked, the custom font returns.

this is the custom textbox class that i'm using (the FontManager class works fine so I didn't include it, but I can do it if you ask me for it)

Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Text

Public Class WaterMarkTextBox
    Inherits TextBox
    Private oldFont As Font = Nothing
    Private waterMarkTextEnabled As Boolean = False
    Private myFontCollection As PrivateFontCollection = New PrivateFontCollection()

#Region "Attributes"
    Private _waterMarkColor As Color = Drawing.Color.Gray
    Public Property WaterMarkColor() As Color
        Get
            Return _waterMarkColor
        End Get
        Set(ByVal value As Color)
            _waterMarkColor = value
            Me.Invalidate()
        End Set
    End Property

    Private _waterMarkText As String = "Watermark"

    Public Property WaterMarkText() As String
        Get
            Return _waterMarkText
        End Get
        Set(ByVal value As String)
            _waterMarkText = value
            Me.Invalidate()
        End Set
    End Property
#End Region

    Public Sub New()
        Dim installedFontsCount = FontManager.AddFontsFromResources(myFontCollection, {"minecraft_font"})
    End Sub
    
    Private Sub WaterMark_Toggle() 
        If Me.Text.Length <= 0 Then
            EnableWaterMark()
        Else
            DisableWaterMark()
        End If
    End Sub

    Private Sub EnableWaterMark()
        oldFont = New Font(myFontCollection.Families(0), 8, FontStyle.Italic, Font.Unit)
        Me.SetStyle(ControlStyles.UserPaint, True)
        Me.waterMarkTextEnabled = True
        Refresh()
    End Sub

    Private Sub DisableWaterMark()
        Me.waterMarkTextEnabled = False
        Me.SetStyle(ControlStyles.UserPaint, True)
        If Not oldFont Is Nothing Then
            Me.Font = New Font(myFontCollection.Families(0), 9, FontStyle.Regular, Font.Unit)
        End If
        Refresh()
    End Sub

    Protected Overrides Sub OnHandleCreated(e As EventArgs)
        WaterMark_Toggle()
        MyBase.OnHandleCreated(e)
    End Sub

    Protected Overrides Sub OnEnter(ByVal e As EventArgs)
        WaterMark_Toggle()
        MyBase.OnEnter(e)
    End Sub

    Protected Overrides Sub Dispose(disposing As Boolean)
        If disposing Then myFontCollection.Dispose()
        MyBase.Dispose(disposing)
    End Sub

    Protected Overrides Sub OnTextChanged(e As EventArgs)
        MyBase.OnTextChanged(e)
        WaterMark_Toggle()
    End Sub

    Protected Overrides Sub OnLeave(e As EventArgs)
        WaterMark_Toggle()
        MyBase.OnLeave(e)
    End Sub

    Protected Overrides Sub OnFontChanged(e As EventArgs)
        If waterMarkTextEnabled Then
            oldFont = New Font(myFontCollection.Families(0), 9, FontStyle.Regular, Font.Unit)
            Refresh()
        End If
        MyBase.OnFontChanged(e)
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim drawFont As Font 
        If waterMarkTextEnabled = True Then
            _waterMarkColor = Drawing.Color.Gray
            drawFont = New Font(myFontCollection.Families(0), 9, FontStyle.Italic, Font.Unit)
        Else
            _waterMarkColor = Drawing.Color.Black
            drawFont = New Font(myFontCollection.Families(0), 9, FontStyle.Regular, Font.Unit)
        End If
        Dim drawBrush As SolidBrush = New SolidBrush(Me.WaterMarkColor)
        e.Graphics.DrawString(IIf(waterMarkTextEnabled, WaterMarkText, Text).ToString(), drawFont, drawBrush, New Point(0, 0))
        MyBase.OnPaint(e)
    End Sub
End Class

Also, I would like to know how to always show the end of a textbox string, not only when the control has the focus or the cursor or how to put an autoellipsis at the beginning, for example: ...ocuments\Proyect.txt I'm working with files and directories but I don't want to divide it by \ or just show the name of the file, I want to put a tooltip on it and the user can copy the full address from the textbox. (the latter is not important.)

Rchrd
  • 35
  • 1
  • 8
  • 1
    Are you aware that "cue banner" functionality (the official name) is built into Windows? Not sure if there are any specific implications relating to your font requirements but you should look into calling the `SendMessage` API with the `EM_SETCUEBANNER` message to have Windows draw the prompt text. – jmcilhinney Oct 28 '20 at 04:48
  • @jmcilhinney sorry but I don't understand a single thing you said, I'm new to creating controls. – Rchrd Oct 28 '20 at 04:55
  • Here's a [cue-banner for TextBox and ComboBox](https://stackoverflow.com/a/59803179/7444103), as extension methods. Of course you can use that same code directly. – Jimi Oct 28 '20 at 05:16
  • Does this answer your question? [watermark Text-box Align Center](https://stackoverflow.com/questions/41485621/watermark-text-box-align-center). See accepted answer for all the detail you need to enable the Cue Banner feature on Windows platforms. – Peter Duniho Oct 28 '20 at 05:25
  • Does this answer your question? [Placeholder in TextBox in Window Forms using VB.NET](https://stackoverflow.com/questions/50924572/placeholder-in-textbox-in-window-forms-using-vb-net) – Peter Duniho Oct 28 '20 at 05:30
  • Does this answer your question? [Watermark TextBox in WinForms](https://stackoverflow.com/questions/4902565/watermark-textbox-in-winforms) – Peter Duniho Oct 28 '20 at 05:30
  • You can be new to creating controls but you're not new to the world. You understand the words in my post, you know how to determine what the keywords are in a statement and you know how to use a search engine. What more do you need? Pick the keywords out of my comment and do the appropriate web searches. You should find much, if not all, of what you need. If you need more, you can ask more specific questions. – jmcilhinney Oct 28 '20 at 06:40

0 Answers0