C# .NET - Custom WaterMark TextBox for Windows Forms - C#.Net

Asked By Developer Developer on 07-Nov-11 09:19 AM
hi all,

i want to know how to create "Custom WaterMark TextBox for Windows Forms" using C#.NET for Window Application.
Neha Garg replied to Developer Developer on 07-Nov-11 09:49 AM
Hello DD,

See the example of Custom WaterMark TextBox:



Option Strict On
Imports System
Imports System.Windows.Forms
Imports System.Drawing
Public Class WaterMarkTextBox
   
Inherits TextBox
 
   
Private oldFont As Font = Nothing
   
Private waterMarkTextEnabled As Boolean = False
 
#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 = "Water Mark"
 
   
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
 
   
' Default constructor
    Public Sub New()
        JoinEvents(True)
    End Sub
 
    Private Sub JoinEvents(ByVal join As Boolean)
        If join Then
            AddHandler (TextChanged), AddressOf WaterMark_Toggle
            AddHandler (LostFocus), AddressOf WaterMark_Toggle
            AddHandler (FontChanged), AddressOf WaterMark_FontChanged
            '
No one of the above events will start immeddiatlly
           
'TextBox control still in constructing, so,
            '
Font object (for example) couldn't be catched from within WaterMark_Toggle
            '
So, call WaterMark_Toggel through OnCreateControl after TextBox is totally created
           
'No doupt, it will be only one time call
 
            '
Old solution uses Timer.Tick event to check Create property
       
End If
   
End Sub
 
   
Private Sub WaterMark_Toggle(ByVal sender As Object, ByVal args As EventArgs)
       
If Me.Text.Length <= 0 Then
           
EnableWaterMark()
       
Else
           
DisableWaterMark()
       
End If
   
End Sub
 
   
Private Sub WaterMark_FontChanged(ByVal sender As Object, ByVal args As EventArgs)
       
If waterMarkTextEnabled Then
            oldFont
= New Font(Font.FontFamily, Font.Size, Font.Style, Font.Unit)
           
Refresh()
       
End If
   
End Sub
 
   
Private Sub EnableWaterMark()
       
'Save current font until returning the UserPaint style to false (NOTE: It is a try and error advice)
        oldFont = New Font(Font.FontFamily, Font.Size, Font.Style, Font.Unit)
 
        '
Enable OnPaint Event Handler
       
Me.SetStyle(ControlStyles.UserPaint, True)
       
Me.waterMarkTextEnabled = True
 
       
'Trigger OnPaint immediatly
        Refresh()
 
    End Sub
 
    Private Sub DisableWaterMark()
        '
Disbale OnPaint event handler
       
Me.waterMarkTextEnabled = False
       
Me.SetStyle(ControlStyles.UserPaint, False)
 
       
'Return oldFont if existed
        If Not oldFont Is Nothing Then
            Me.Font = New Font(Font.FontFamily, Font.Size, Font.Style, Font.Unit)
        End If
    End Sub
 
    '
Override OnCreateControl
   
Protected Overrides Sub OnCreateControl()
       
MyBase.OnCreateControl()
       
WaterMark_Toggle(Nothing, Nothing)
   
End Sub
 
   
' Override OnPaint
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        '
Use the same font that was defined in base class
       
Dim drawFont As Font = New Font(Font.FontFamily, Font.Size, Font.Style, Font.Unit)
       
' Create new brush with gray color or
        Dim drawBrush As SolidBrush = New SolidBrush(Me.WaterMarkColor) '
use WaterMarkColor
       
' Draw Test or WaterMark
        e.Graphics.DrawString(IIf(waterMarkTextEnabled, WaterMarkText, Text).ToString(), drawFont, drawBrush, New Point(0, 0))
        MyBase.OnPaint(e)
    End Sub
 
End Class

Compile application to use new WaterMarkTextBox control


Compile the application.  You should now see a "<Your Project Name> Components" section on your toolbox with a tool called WaterMarkTextBox

Use the new WaterMarkTextBox control


Drag the new control from your toolbox onto your form and you can set the properties in the properties window (WaterMarkColor, WaterMarkText)
Neha Garg replied to Developer Developer on 07-Nov-11 09:52 AM
Hello Developer,

See the well explained answers on the below mentioned links:

http://www.codeproject.com/KB/miscctrl/WaterMark.aspx

http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/A_362-Custom-WaterMark-TextBox-for-Windows-Forms-VB-Net.html

Developer Developer replied to Neha Garg on 07-Nov-11 09:53 AM
this is in vb.net

the code provided by you is already available here
http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/A_362-Custom-WaterMark-TextBox-for-Windows-Forms-VB-Net.html


i want code in C#
Kirtan Patel replied to Developer Developer on 07-Nov-11 10:05 AM
you need to create your own custom control to do that  code custom control like this to make it 

Untitled document
class WatermarkTextBox : TextBox
{
  private const uint ECM_FIRST = 0x1500;
  private const uint EM_SETCUEBANNER = ECM_FIRST + 1;
 
  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
  static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
 
  private string watermarkText;
  public string WatermarkText
  {
    get { return watermarkText; }
    set
    {
      watermarkText = value;
      SetWatermark(watermarkText);
    }
  }
 
  private void SetWatermark(string watermarkText)
  {
    SendMessage(this.Handle, EM_SETCUEBANNER, 0, watermarkText);
  }     
 
}
 
dipa ahuja replied to Developer Developer on 07-Nov-11 10:12 AM
You just need to impelement the textbox's Leave and enter event

1. set the forecolor of textbox = gray (for watermark look) and Italic = true in Form_Load

private void Form1_Load(object sender, EventArgs e)
{
  textBox1.Font = new Font(textBox1.Font, FontStyle.Italic);
  textBox1.ForeColor = System.Drawing.Color.Gray;  
}

2. Implement the textBox's Leave and enter Event:

private void textBox1_Enter(object sender, EventArgs e)
{
  textBox1.Text = "";
}
 
private void textBox1_Leave(object sender, EventArgs e)
{
  if (textBox1.Text == "")
  {
    textBox1.Text = "Enter Name";
  }
  else
  {
    textBox1.Font = new Font(textBox1.Font, FontStyle.Regular);
    textBox1.ForeColor = System.Drawing.Color.Black;
  }
}
Done!

Jitendra Faye replied to Developer Developer on 07-Nov-11 11:33 PM
Try this code-

using System;

using

System.Collections.Generic;

using

System.Linq;

using

System.Text;

using

System.Windows.Forms;

using

System.Drawing;

namespace

wmgCMS

{


class WaterMarkTextBox : TextBox

{


private Font oldFont = null;

private Boolean waterMarkTextEnabled = false;

#region

Attributes

private Color _waterMarkColor = Color.Gray;



public
Color WaterMarkColor

{


get { return _waterMarkColor; }

set { _waterMarkColor = value; Invalidate();/*thanks to Bernhard Elbl

for Invalidate()*/

}

}


private string _waterMarkText = "Water Mark";

public string WaterMarkText

{


get { return _waterMarkText; }

set { _waterMarkText = value; Invalidate(); }

}

#endregion

//Default constructor

public WaterMarkTextBox()

{

JoinEvents(

true);

}


//Override OnCreateControl ... thanks to "lpgray .. codeproject guy"

protected override void OnCreateControl()

{


base.OnCreateControl();

WaterMark_Toggel(null, null);

}


//Override OnPaint

protected override void OnPaint(PaintEventArgs args)

{


// Use the same font that was defined in base class

System.Drawing.Font drawFont = new System.Drawing.Font(Font.FontFamily,

Font.Size, Font.Style, Font.Unit);


//Create new brush with gray color or

SolidBrush drawBrush = new SolidBrush(WaterMarkColor);//use Water mark color

//Draw Text or WaterMark

args.Graphics.DrawString((waterMarkTextEnabled ? WaterMarkText : Text),

drawFont, drawBrush,

new PointF(0.0F, 0.0F));

base.OnPaint(args);

}


private void JoinEvents(Boolean join)

{


if (join)

{


this.TextChanged += new System.EventHandler(this.WaterMark_Toggel);

this.LostFocus += new System.EventHandler(this.WaterMark_Toggel);

this.FontChanged += new System.EventHandler(this.WaterMark_FontChanged);

//No one of the above events will start immeddiatlly

//TextBox control still in constructing, so,

//Font object (for example) couldn't be catched from within

//WaterMark_Toggle

//So, call WaterMark_Toggel through OnCreateControl after TextBox

//is totally created

//No doupt, it will be only one time call


//Old solution uses Timer.Tick event to check Create property

}

}


private void WaterMark_Toggel(object sender, EventArgs args )

{


if (this.Text.Length <= 0)

EnableWaterMark();


else

DisbaleWaterMark();

}


private void EnableWaterMark()

{


//Save current font until returning the UserPaint style to false (NOTE:

//It is a try and error advice)

oldFont = new System.Drawing.Font(Font.FontFamily, Font.Size, Font.Style,

Font.Unit);


//Enable OnPaint event handler

this.SetStyle(ControlStyles.UserPaint, true);

this.waterMarkTextEnabled = true;

//Triger OnPaint immediatly

Refresh();

}


private void DisbaleWaterMark()

{


//Disbale OnPaint event handler

this.waterMarkTextEnabled = false;

this.SetStyle(ControlStyles.UserPaint, false);

//Return back oldFont if existed

if(oldFont != null)

this.Font = new System.Drawing.Font(oldFont.FontFamily, oldFont.Size,

oldFont.Style, oldFont.Unit);

}


private void WaterMark_FontChanged(object sender, EventArgs args)

{


if (waterMarkTextEnabled)

{

oldFont =

new System.Drawing.Font(Font.FontFamily,Font.Size,Font.Style,

Font.Unit);

Refresh();

}

}

}

}


Follow this link-

http://www.codeproject.com/KB/miscctrl/WaterMark.aspx
Hope this will ghelp you.