using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ShortcutUtil
{
// https://www.codeproject.com/Articles/27849/WaterMark-TextBox-For-Desktop-Applications-Using-C
class WatermarkTextBox : TextBox
{
private Font mOldFont = null;
private Boolean mWaterMarkTextEnabled = 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();
WaterMarkToggle(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((mWaterMarkTextEnabled ? 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.WaterMarkToggle);
this.LostFocus += new System.EventHandler(this.WaterMarkToggle);
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 WaterMarkToggle(object sender, EventArgs args)
{
if (this.Text.Length <= 0)
EnableWaterMark();
else
DisableWaterMark();
}
private void EnableWaterMark()
{
//Save current font until returning the UserPaint style to false (NOTE:
//It is a try and error advice)
mOldFont = new System.Drawing.Font(Font.FontFamily, Font.Size, Font.Style,
Font.Unit);
//Enable OnPaint event handler
this.SetStyle(ControlStyles.UserPaint, true);
this.mWaterMarkTextEnabled = true;
//Triger OnPaint immediatly
Refresh();
}
private void DisableWaterMark()
{
//Disbale OnPaint event handler
this.mWaterMarkTextEnabled = false;
this.SetStyle(ControlStyles.UserPaint, false);
//Return back oldFont if existed
if (mOldFont != null)
this.Font = new System.Drawing.Font(mOldFont.FontFamily, mOldFont.Size,
mOldFont.Style, mOldFont.Unit);
}
private void WaterMark_FontChanged(object sender, EventArgs args)
{
if (mWaterMarkTextEnabled)
{
mOldFont = new System.Drawing.Font(Font.FontFamily, Font.Size, Font.Style,
Font.Unit);
Refresh();
}
}
}
}