Click here to Skip to main content
13,291,748 members (58,653 online)
Click here to Skip to main content
Add your own
alternative version


71 bookmarked
Posted 16 Jul 2008

WaterMark TextBox For Desktop Applications Using C#, .NET 3.5 and VS2008

, 22 Aug 2008
Rate this:
Please Sign up or sign in to vote.
Watermark TextBox for .NET


During my work in a (CMS) Content Management System, and in the module of publishing (which is a .NET desktop application) I needed a watermark feature to help users to know the functionality of a certain TextBox.

WaterMark is a gray text in a TextBox that must disappears once the user starts to input his text, and must again appear if the user erases all of his text characters.


I discovered that TextBox doesn't support this nice feature (am I wrong!?) Whatever, I enjoyed sub classing TextBox to implement a watermark feature myself, it reminded me of the past/nice days of VC++.

It didn't take more than 8 hours to subclass the TextBox control (.NET 3.5) and then obtain a good feature like watermark. I Googled three web-pages or more in order to know how to enable and disable the overriding of the OnPaint handler, where, OnPaint is ignored by default until modifying the control style UserPaint, which can be modified by using the following statement:

this.SetStyle(ControlStyles.UserPaint, true);

And to render WaterMarkText on the client area of the TextBox control it was easy to use PaintEventArgs.DrawString(...), because it works just as easily as setting the TextBox.Text property. Take a look:

args.Graphics.DrawString((WaterMarkTextEnabled ? WaterMarkText : Text),
drawFont, drawBrush, new PointF(0.0F, 0.0F));

I was also in need of subscribing some events to toggle WaterMark On and Off according to the state of the TextBox.Text property. It may be empty (which means WaterMark-enabled) or full of characters (means WaterMark-disabled). This includes events like:

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

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

Careful — while TextBox is in the state of "WaterMark-enabled", the TextBox.Font property seems to be garbage collected after calling this.SetStyle(...). This seems to occur when using the Brush property for example, (you find this by trial and error), so, I was obliged to save TextBox.Font into a oldFont member variable until WaterMark goes to a "disable" state, then returns back to its origin.

TextBox.Font may itself be changed for various reasons (i.e., a user may decide to change the font), so, I was again obliged to subscribe the TextBox.FontChanged event to update oldFont so that at the correct time of modification, subscription is done by using the following statement:

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

At that time, the joined events will not be capable to change the state of TextBox-control/WaterMark-feature, so, the constructor must initialize the WaterMark-toggling process along with joining these events at the time of construction. But, the control isn't yet constructed/created totally, where some members like TextBox.Font are not created, and we will not be able to catch oldFont. So, we must stay waiting for the control for awhile until it is created totally and then call WaterMark_Toggel. To solve that problem I used OnCreateControl handler that makes it possible to trigger WaterMark_Toggel at the end of the creation process (thanks is to 'lpgray' who tolled me about OnCreateControl).

Again, WaterMark toggling is being done by calling WaterMark_Toggel(null,null) which depends on TextBox.Text to decide which state should be assigned to the control (WaterMark-enable or WaterMark-disable). Take a look at the JoinEvents(true) member function.

Using the Code

This code was written on Visual Studio 2008, .NET 3.5 and C#.

To use the code just take a copy from the file WaterMarkTextBox.cs or from the following code snippet, and place it in your project, then, build the project, you will get a component icon on your ToolBox named WaterMarkTextBox. Drag the icon to your form and enjoy WaterMarkText and WaterMarkColor properties.

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(); }

        //Default constructor
        public WaterMarkTextBox()

        //Override OnCreateControl ... thanks to  "lpgray .. codeproject guy"
        protected override void 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));

        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
                //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)

        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,
            //Enable OnPaint event handler
            this.SetStyle(ControlStyles.UserPaint, true);
            this.waterMarkTextEnabled = true;
            //Triger OnPaint immediatly

        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,

Points of Interest

Subclassing .NET controls.


  • 15/6/2008: Posted version 1.0.
  • 9/8/2008: Posted version 1.5. - Use 'OnCreateCotrol' instead of ' Timer.Tick', use 'Invalidate' instead of 'Refresh' and remove unwanted property 'WaterMarkTextEnabled'
  • 22/8/2008: Posted version 1.6. - Update demo application to show how to use WatermarkColor and Font properly.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Wael Alghool
Architect Government
Qatar Qatar
Programmer since 1990 with Pascal, VC++, C#, ASP.NET, jQuery, J2EE and Android.
PMP Certified since 2009.
PSP Certified since 2005.
Business & System analyst since 2004.
Led teams in between 8 to 30 members.
Worked for,,,,

You may also be interested in...


Comments and Discussions

SuggestionFor Center Alignment Pin
shoglaaaaag7-Aug-17 7:24
membershoglaaaaag7-Aug-17 7:24 
QuestionKryptonTextbox Pin
Cool Smith17-Nov-16 22:35
memberCool Smith17-Nov-16 22:35 
QuestionCan we apply RightToLeft property on WaterMarkText? Pin
Member 1227268630-Sep-16 3:21
memberMember 1227268630-Sep-16 3:21 
QuestionGreat Article Pin
Member 1165127712-Feb-16 7:01
memberMember 1165127712-Feb-16 7:01 
Questionhow to increase the height of this water mark Pin
sher_azam27-May-14 2:54
membersher_azam27-May-14 2:54 
Questionwater mark text box Fixed Single Borderstyle Pin
Member 1029340818-Apr-14 1:13
memberMember 1029340818-Apr-14 1:13 
SuggestionThanks! I would recommend... Pin
BigFish20002-Sep-13 20:46
memberBigFish20002-Sep-13 20:46 
GeneralRe: Thanks! I would recommend... Pin
Prem Acharya20-Oct-13 5:47
memberPrem Acharya20-Oct-13 5:47 
GeneralRe: Thanks! I would recommend... Pin
Nazareno Manco7-Oct-15 4:27
memberNazareno Manco7-Oct-15 4:27 
QuestionAdd click event Pin
Member 217319024-Aug-13 7:53
memberMember 217319024-Aug-13 7:53 
QuestionMore Readable Pin
NehruKandasamy4-Mar-13 19:01
memberNehruKandasamy4-Mar-13 19:01 
AnswerRe: More Readable Pin
Wael Alghool6-Mar-13 18:40
memberWael Alghool6-Mar-13 18:40 
GeneralMy vote of 5 Pin
Renju Vinod6-Feb-13 20:27
memberRenju Vinod6-Feb-13 20:27 
SuggestionPlease update the code section. Pin
Malli_S24-Jan-12 20:49
memberMalli_S24-Jan-12 20:49 
GeneralMy 4. Pin
Malli_S24-Jan-12 20:47
memberMalli_S24-Jan-12 20:47 
GeneralMy vote of 2 Pin
Sharad Kulkarni13-Oct-10 20:07
memberSharad Kulkarni13-Oct-10 20:07 
GeneralMy vote of 3 Pin
sunilmcahnbgu12-Sep-10 21:14
membersunilmcahnbgu12-Sep-10 21:14 
GeneralThats wrong Pin
Xmen W.K.20-Jun-10 16:01
memberXmen W.K.20-Jun-10 16:01 
GeneralRe: Thats wrong Pin
Romulus C.1-Nov-10 4:35
memberRomulus C.1-Nov-10 4:35 
GeneralRe: Thats wrong Pin
Xmen W.K.2-Nov-10 16:12
memberXmen W.K.2-Nov-10 16:12 
GeneralVisual Studio 2003 Pin
ssaresky8-Apr-10 5:37
memberssaresky8-Apr-10 5:37 
GeneralA small change. Pin
Romulus C.15-Oct-08 5:24
memberRomulus C.15-Oct-08 5:24 
GeneralWith only one character, watermark is still present Pin
dfjohn00519-Aug-08 0:12
memberdfjohn00519-Aug-08 0:12 
GeneralRe: With only one character, watermark is still present [modified] Pin
Stumproot19-Aug-08 0:49
memberStumproot19-Aug-08 0:49 
GeneralRe: With only one character, watermark is still present Pin
Wael Alghool21-Aug-08 23:36
memberWael Alghool21-Aug-08 23:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.171207.1 | Last Updated 22 Aug 2008
Article Copyright 2008 by Wael Alghool
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid