Click here to Skip to main content
15,893,904 members
Articles / Programming Languages / C#

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

Rate me:
Please Sign up or sign in to vote.
4.54/5 (35 votes)
22 Aug 2008CPOL3 min read 250K   9.8K   74  
Watermark TextBox for .NET
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;
        Timer timer = new Timer();

        #region Attributes 
            private Color _waterMarkColor = Color.Gray;
            public Color WaterMarkColor
            {
                get { return _waterMarkColor; }
                set { _waterMarkColor = value; if (this.Created) Refresh(); }
            }

            private string _waterMarkText = "Water Mark";
            public string WaterMarkText
            {
                get { return _waterMarkText; }
                set { _waterMarkText = value; if (this.Created) Refresh(); }
            }
            
            //Private attribute
            private Boolean _waterMarkTextEnabled = false;
            private Boolean WaterMarkTextEnabled
            {
                get { return _waterMarkTextEnabled; }
                set { _waterMarkTextEnabled = value; }
            }
        #endregion

        //Default constructor
        public WaterMarkTextBox()
        {
            JoinEvents(true);
        }

        //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 timer_Tick after TextBox is totally created
                //No doupt, it will be only one time call then kill the timer object
                timer.Tick += new EventHandler(timer_Tick);
                timer.Interval = 100;
                timer.Start();
            }
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (Created)
            {
                WaterMark_Toggel(null, null);
                timer.Stop();
                timer = null;
            }
        }

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

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
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 www.beinsports.net, www.harf.com, www.islamweb.net, islam.gov.qa, islamonline.net.

Comments and Discussions