我试图弄清楚是否有可能以及是否有人知道如何制作此Cue Banner(Watermark) 文本框的多行版本。我得到了这个工作正常的单行版本,但对于我的项目,我真的需要一个多行,在加载时在框中有一段文本,当用户点击文本时,只要他们在框中输入一些内容它消失了,但是如果他们删除了他们在文本框中输入的任何内容,我的段落就会返回。我希望这是有道理的。
感谢您的任何回复。
我试图弄清楚是否有可能以及是否有人知道如何制作此Cue Banner(Watermark) 文本框的多行版本。我得到了这个工作正常的单行版本,但对于我的项目,我真的需要一个多行,在加载时在框中有一段文本,当用户点击文本时,只要他们在框中输入一些内容它消失了,但是如果他们删除了他们在文本框中输入的任何内容,我的段落就会返回。我希望这是有道理的。
感谢您的任何回复。
我搜索了一下,找到了一个更好的解决方案,适用于多行和单行文本框:
// Thank you author of http://nate.deepcreek.org.au/svn/tools/ComskipToCuttermaran/trunk/CSharpControls/GlassTextBox.cs
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class CueTextBox : TextBox
{
#region Fields
private Bitmap _bitmap;
private bool _paintedFirstTime = false;
const int WM_PAINT = 0x000F;
const int WM_PRINT = 0x0317;
const int PRF_CLIENT = 0x00000004;
const int PRF_ERASEBKGND = 0x00000008;
private string _cue;
#endregion
#region Properties
public string Cue
{
get { return _cue; }
set {
_cue = value;
Invalidate(true);
}
}
public new BorderStyle BorderStyle
{
get { return base.BorderStyle; }
set {
if (_paintedFirstTime)
SetStyle(ControlStyles.UserPaint, false);
base.BorderStyle = value;
if (_paintedFirstTime)
SetStyle(ControlStyles.UserPaint, true);
}
}
public override bool Multiline
{
get { return base.Multiline; }
set {
if (_paintedFirstTime)
SetStyle(ControlStyles.UserPaint, false);
base.Multiline = value;
if (_paintedFirstTime)
SetStyle(ControlStyles.UserPaint, true);
}
}
#endregion
#region Constructor
public CueTextBox()
: base()
{
SetStyle(ControlStyles.UserPaint, false);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
}
#endregion
#region Functions
[DllImport("USER32.DLL", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
protected override void Dispose(bool disposing)
{
if (_bitmap != null)
_bitmap.Dispose();
base.Dispose(disposing);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_PAINT)
{
_paintedFirstTime = true;
CaptureBitmap();
SetStyle(ControlStyles.UserPaint, true);
base.WndProc(ref m);
SetStyle(ControlStyles.UserPaint, false);
return;
}
base.WndProc(ref m);
}
private void CaptureBitmap()
{
if (_bitmap != null)
_bitmap.Dispose();
_bitmap = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height, PixelFormat.Format32bppArgb);
using (var graphics = Graphics.FromImage(_bitmap))
{
int lParam = PRF_CLIENT | PRF_ERASEBKGND;
System.IntPtr hdc = graphics.GetHdc();
SendMessage(this.Handle, WM_PRINT, hdc, new IntPtr(lParam));
graphics.ReleaseHdc(hdc);
}
}
protected override void OnPaint(PaintEventArgs e)
{
SetStyle(ControlStyles.UserPaint, true);
if (_bitmap == null)
e.Graphics.FillRectangle(Brushes.CornflowerBlue, ClientRectangle);
else
e.Graphics.DrawImageUnscaled(_bitmap, 0, 0);
if (_cue != null && Text.Length == 0)
e.Graphics.DrawString(_cue, Font, Brushes.Gray, -1f, 1f);
SetStyle(ControlStyles.UserPaint, false);
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
Invalidate();
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
Invalidate();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
Invalidate();
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
Invalidate();
}
protected override void OnFontChanged(EventArgs e)
{
if (_paintedFirstTime)
SetStyle(ControlStyles.UserPaint, false);
base.OnFontChanged(e);
if (_paintedFirstTime)
SetStyle(ControlStyles.UserPaint, true);
}
#endregion
}
基本上我使用了 GlassTextBox 的代码,并在 OnPaint 函数中添加了几行代码来绘制提示。