using System; using System.Collections.Generic; 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); EnableWaterMark(); } //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 float xpoint = ((float)args.ClipRectangle.Width / 2.0F) - ((float)TextRenderer.MeasureText(WaterMarkText, Font).Width / 2.0F); ; PointF centeredtext = new PointF(xpoint, 0.0F); args.Graphics.DrawString((waterMarkTextEnabled ? WaterMarkText : Text), drawFont, drawBrush, centeredtext); 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.GotFocus += new System.EventHandler(this.WaterMark_Toggel); this.MouseCaptureChanged += 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(); */ /*if (this.Text.Length > 0) { System.Diagnostics.Debug.WriteLine(sender.ToString() + " disabled watermark"); DisbaleWaterMark(); }*/ 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(); } } } }