Can anyone point me to a good implementation of a basic Windows Forms TextBox that will initially show watermark text that disappears when the cursor enters it? I think I ca
With .Net Core 3 a property was introduced into TextBox: PlaceHolderText
If one is going to need this in a FrameWork application the required code parts can be taken from the official open source code and placed in a TextBox descendant (see license).
This supports multiline TextBox and also RTL text.
public class PlaceHolderTextBox : TextBox
{
private const int WM_KILLFOCUS = 0x0008;
private const int WM_PAINT = 0x000F;
private string _placeholderText;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (this.ShouldRenderPlaceHolderText(m))
{
using Graphics g = this.CreateGraphics();
this.DrawPlaceholderText(g);
}
}
#region PlaceHolder
///
/// Gets or sets the text that is displayed when the control has no text and does not have the focus.
///
/// The text that is displayed when the control has no text and does not have the focus.
[Localizable(true), DefaultValue("")]
public virtual string PlaceholderText
{
get => _placeholderText;
set
{
if (value == null)
{
value = string.Empty;
}
if (_placeholderText != value)
{
_placeholderText = value;
if (this.IsHandleCreated)
{
this.Invalidate();
}
}
}
}
//-------------------------------------------------------------------------------------------------
///
/// Draws the in the client area of the using the default font and color.
///
private void DrawPlaceholderText(Graphics graphics)
{
TextFormatFlags flags = TextFormatFlags.NoPadding | TextFormatFlags.Top |
TextFormatFlags.EndEllipsis;
Rectangle rectangle = this.ClientRectangle;
if (this.RightToLeft == RightToLeft.Yes)
{
flags |= TextFormatFlags.RightToLeft;
switch (this.TextAlign)
{
case HorizontalAlignment.Center:
flags |= TextFormatFlags.HorizontalCenter;
rectangle.Offset(0, 1);
break;
case HorizontalAlignment.Left:
flags |= TextFormatFlags.Right;
rectangle.Offset(1, 1);
break;
case HorizontalAlignment.Right:
flags |= TextFormatFlags.Left;
rectangle.Offset(0, 1);
break;
}
}
else
{
flags &= ~TextFormatFlags.RightToLeft;
switch (this.TextAlign)
{
case HorizontalAlignment.Center:
flags |= TextFormatFlags.HorizontalCenter;
rectangle.Offset(0, 1);
break;
case HorizontalAlignment.Left:
flags |= TextFormatFlags.Left;
rectangle.Offset(1, 1);
break;
case HorizontalAlignment.Right:
flags |= TextFormatFlags.Right;
rectangle.Offset(0, 1);
break;
}
}
TextRenderer.DrawText(graphics, this.PlaceholderText, this.Font, rectangle, SystemColors.GrayText, this.BackColor, flags);
}
private bool ShouldRenderPlaceHolderText(in Message m) =>
!string.IsNullOrEmpty(this.PlaceholderText) &&
(m.Msg == WM_PAINT || m.Msg == WM_KILLFOCUS) &&
!this.GetStyle(ControlStyles.UserPaint) &&
!this.Focused && this.TextLength == 0;
#endregion
}