0

我试图弄清楚是否有可能以及是否有人知道如何制作此Cue Banner(Watermark) 文本框的多行版本。我得到了这个工作正常的单行版本,但对于我的项目,我真的需要一个多行,在加载时在框中有一段文本,当用户点击文本时,只要他们在框中输入一些内容它消失了,但是如果他们删除了他们在文本框中输入的任何内容,我的段落就会返回。我希望这是有道理的。

感谢您的任何回复。

4

1 回答 1

1

我搜索了一下,找到了一个更好的解决方案,适用于多行和单行文本框:

// 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 函数中添加了几行代码来绘制提示。

于 2013-10-09T13:42:51.083 回答