WinForms中的水印文本框 [英] Watermark TextBox in WinForms

查看:24
本文介绍了WinForms中的水印文本框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能指出一个基本的 Windows 窗体 TextBox 的良好实现,它最初会显示当光标进入时消失的水印文本?我想我可以创造性地使用 Enter 和 Leave 事件来创建我自己的,但我确信在某个地方有一个完全可用的实现.我看到了 WPF 实现,如有必要,我可以嵌套它,但原生 WinForms TextBox 衍生产品会更好.

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 can create my own with some creative use of Enter and Leave events, but I'm sure there's a perfectly usable implementation sitting around somewhere. I saw the WPF implementation and if necessary I could nest it, but a native WinForms TextBox derivative would be better.

到目前为止,我有这个;还没有尝试过,但有没有人发现任何明显的问题?

I have this so far; haven't tried it yet but does anyone see any glaring problems?

public class WatermarkTextBox:TextBox
{
    public string WatermarkText { get; set; }

    public Color WatermarkColor { get; set; }

    private Color TextColor { get; set; }

    private bool isInTransition;

    public WatermarkTextBox()
    {
        WatermarkColor = SystemColors.GrayText;
    }

    private bool HasText { get { return Text.IsNotNullOrBlankOr(WatermarkText); }}

    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);

        if (HasText) return;

        isInTransition = true;
        ForeColor = TextColor;
        Text = String.Empty;
        isInTransition = false;
    }

    protected override void OnForeColorChanged(EventArgs e)
    {
        base.OnForeColorChanged(e);
        if (!isInTransition) //the change came from outside
            TextColor = ForeColor;
    }

    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);

        if (HasText) return;

        isInTransition = true;
        ForeColor = WatermarkColor;
        Text = WatermarkText.EmptyIfNull();
        isInTransition = false;
    }
}

以上内容最终会通过一些技巧来工作,但 CueProvider 工作得更好.这是我的最终实现:

The above would have eventually worked with some finessing, but the CueProvider worked much better. Here's my final implementation:

public class WatermarkTextBox:TextBox
{
    private string watermarkText;
    public string WatermarkText
    {
        get { return watermarkText; }
        set
        {
            watermarkText = value;
            if (watermarkText.IsNullOrBlank())
                CueProvider.ClearCue(this);
            else
                CueProvider.SetCue(this, watermarkText);
        }
    }
}

我本可以完全集成 CueProvider 功能,但这很好用.

I could have integrated the CueProvider functionality completely, but this works beautifully.

推荐答案

官方名称是cue banner".这是另一种方法,只需继承 TextBox 也可以完成工作.向您的项目添加一个新类并粘贴如下所示的代码.编译.从工具箱顶部拖放新控件并设置 Cue 属性.

The official term is "cue banner". Here's another way to do it, just inheriting TextBox gets the job done too. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox and set the Cue property.

您可以在设计器中实时预览 Cue 值,并本地化为表单的 Language 属性.物超所值,很好地展示了 Winforms 的优点.

You get a live preview of the Cue value in the designer, localized to the form's Language property. Lots of bang for very little buck, an excellent demonstration of the good parts of Winforms.

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class CueTextBox : TextBox {
    [Localizable(true)]
    public string Cue {
        get { return mCue; }
        set { mCue = value; updateCue(); }
    }

    private void updateCue() {
        if (this.IsHandleCreated && mCue != null) {
            SendMessage(this.Handle, 0x1501, (IntPtr)1, mCue);
        }
    }
    protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        updateCue();
    }
    private string mCue;

    // PInvoke
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, string lp);
}

这篇关于WinForms中的水印文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆