Windows Develop Bookmark and Share   
 index > Windows Forms General > Watermark TextBox in winform
 

Watermark TextBox in winform

Trying to create a control like Atlas control that will put a watermark inside a textbox while it is empty.

My original idea was use UserControl1_Enter and UserControl1_Leave and set this.Text appropriately, but this method could foul up other code using the Text property.

My next idea was to use the Paint method, but I am not even sure that TextBox has a OnPaint event at all.

Any tips?

Jon Masters  Sunday, September 17, 2006 1:39 AM

Jon,
as far as I know there is no way you can override the painting the a TextBox control, short of drawing everything yourself.

There is a solution that should do the trick for you, though. You will need to sublcass the TextBox and override a few things. Consider the following code I put together (far from thouroughly tested and polished):

public partial class WatermarkBox : TextBox {
private string watermark;
private Color watermarkColor;
private Color foreColor;
private bool empty;

[Browsable (true)]
public Color WatermarkColor {
get { return watermarkColor; }
set {
watermarkColor =
value;
if (empty) {
base.ForeColor = watermarkColor;
}
}
}

[Browsable(true)]
public string Watermark {
get { return watermark; }
set {
watermark =
value;
if (empty) {
base.Text = watermark;
base.ForeColor = watermarkColor;
}
}
}

public WatermarkBox () {
empty =
true;
foreColor = ForeColor;
}

[Browsable(true)]
public new Color ForeColor {
get { return foreColor; }
set {
foreColor =
value;
if (! empty)
base.ForeColor = value;
}
}

public override string Text {
get {
if (empty)
return "";
return base.Text;
}
set {
if (value == "") {
empty =
true;
base.ForeColor = watermarkColor;
base.Text = watermark;
}
else
base.Text = value;
}
}

protected override void OnGotFocus (EventArgs e) {
if (empty) {
empty =
false;
base.ForeColor = foreColor;
base.Text = "";
}
base.OnGotFocus (e);
}

protected override void OnLostFocus (EventArgs e) {
base.OnLostFocus (e);
if (base.Text == "") {
empty =
true;
base.ForeColor = watermarkColor;
base.Text = watermark;
}
else
empty =
false;
}
}

In a nutshell it does what you were trying to do, but it shouldn't mess the Text property for the other users.

A few comments...

Wenow havetwo brand new properties, Watermark and WatermarkColor that will appear in the designer properties thanks to the Browsable attribute (you can improve on them by setting the category and other amenities). These are obviously the text we want to display as a watermark and the color the watermark should appear in.

The properties Text and ForeColor were also re-declared, but they were not overridden, but hidden. This is due to the fact that the painting functions would have seen our overridden version, and so we would have been unable to report the correct values to functions inspecting the Text or the ForeColor property.

The rest is quite simple. The control will be cleared when it gets the focus and will eventually restore the watermark, if needed, when the focus is lost.

HTH
--mc

Mario Cossi  Sunday, September 17, 2006 3:05 AM

Great solution to the problem.. I had to make a few tweaks to fit, but it was close enough to get me there. Here is my end code:

public partial class WatermarkTextBox : TextBox

{

public WatermarkTextBox()

{

InitializeComponent();

}

private string watermarkText;

private Color watermarkColor;

private Color foreColor;

private bool empty;

[Browsable(true)]

public new Color ForeColor

{

get { return foreColor; }

set

{

foreColor = value;

if (!empty)

base.ForeColor = value;

}

}

[Browsable(true)]

public Color WatermarkColor

{

get { return watermarkColor; }

set

{

watermarkColor = value;

if (empty)

{

base.ForeColor = watermarkColor;

}

}

}

[Browsable(true)]

public string WatermarkText

{

get

{

return watermarkText;

}

set

{

watermarkText = value;

if (base.Text.Length == 0)

{

empty = true;

base.Text = watermarkText;

base.ForeColor = watermarkColor;

}

Invalidate();

}

}

public override string Text

{

get

{

if (empty)

return "";

return base.Text;

}

set

{

if (value == "")

{

empty = true;

base.ForeColor = watermarkColor;

base.Text = watermarkText;

}

else

{

empty = false;

base.ForeColor = foreColor;

base.Text = value;

}

}

}

private void UserControl1_Enter(object sender, EventArgs e)

{

if (empty)

{

empty = false;

base.ForeColor = foreColor;

base.Text = "";

}

}

private void UserControl1_Leave(object sender, EventArgs e)

{

if (base.Text == "")

{

empty = true;

base.ForeColor = watermarkColor;

base.Text = watermarkText;

}

else

{

empty = false;

}

}

}

Jon Masters  Monday, September 18, 2006 12:19 AM
Have any of you guys workimplemented a Watermark textbox that also supports the PasswordChar property?
Holm76  Wednesday, June 27, 2007 7:42 AM

You can use google to search for other answers

Custom Search

More Threads

• datagridview issue.
• Multiple windows on one form
• hi ,does some body here ever use PropertyGrid?
• Merging MenuStrips
• Runtime exception in VB.NET Windows Application
• help with treeview
• Beginners trouble
• Combox item problem
• [otp]Master pages, skins and themes in windows form
• Form Resizing Problem