显示占位符时返回空字符串

时间:2017-07-08 16:04:30

标签: c# properties

我有一个带占位符效果的自定义文本框。如果文本框为空,则显示占位符。

当我将文本框的值(当文本框为空并且显示占位符时)传递给函数时,它会传递占位符值,但我希望它只传递一个空字符串。

enter image description here

我考虑过覆盖Text属性并进行内部检查。像

这样的东西
public string Text
{
    get
    {
        if (this.Text == this.Placeholder)
        {
            return "";
        }
        return this.Text;
    }
    set
    {
        this.Text = value;
    }
}

但我不知道这是否可行。我认为这会产生无限循环。我如何使这项工作?

我知道我可以使用自定义属性(例如,ActualText代替Text)来执行此操作,但如果可行,我想使用Text。如果没有,我将使用自定义属性。

using System;
using System.Drawing;
using System.Windows.Forms;
using CustomExtensions;

namespace CustomControls
{
    public class CustomTextBox : TextBox
    {
        private string _placeholder;

        public string Placeholder
        {
            get
            {
                return this._placeholder;
            }
            set
            {
                this._placeholder = value;
                if (value.IsEmpty(true))
                {
                    this._placeholder = "";
                }
                else
                {
                    this._placeholder = value;
                }
            }
        }

        public CustomTextBox()
        {
            Initialize();
        }

        private void Initialize()
        {
            this.Enter += new EventHandler(this.Placeholder_Hide);
            this.Leave += new EventHandler(this.Placeholder_Show);
        }

        // called from MainForm_Load
        public void InitPH()
        {
            if (!this.Placeholder.IsEmpty(true) && this.Text.IsEmpty())
            {
                this.Text = this.Placeholder;
                this.ForeColor = Color.Gray;
                this.Font = new Font("Segoe UI", 10.2F, FontStyle.Italic);
            }
        }

        private void Placeholder_Hide(object sender, EventArgs e)
        {
            if (this.Text == this._placeholder)
            {
                this.Text = "";
                this.ForeColor = Color.Black;
                this.Font = new Font("Segoe UI", 10.2F, FontStyle.Regular);
            }
        }

        private void Placeholder_Show(object sender, EventArgs e)
        {
            if (this.IsEmpty())
            {
                this.Text = this._placeholder;
                this.ForeColor = Color.Gray;
                this.Font = new Font("Segoe UI", 10.2F, FontStyle.Italic);
            }
        }

        public bool IsEmpty()
        {
            return this.Text.IsEmpty(true, this.Placeholder);
        }
    }
}

2 个答案:

答案 0 :(得分:2)

最好不要if (this.Text == this._placeholder),因为如果有人实际输入与占位符相同的文本呢?这可能不太可能,但你不想留下意外行为的可能性。

一种可能的替代方案如下:

在类_valueIsSet的类bool中添加一个字段。然后,修改事件处理程序以相应地设置它。

private void _valueIsSet = false;

private void Placeholder_Hide(object sender, EventArgs e)
{
    if (!this._valueIsSet)
    {
        this.Text = "";
        this.ForeColor = Color.Black;
        this.Font = new Font("Segoe UI", 10.2F, FontStyle.Regular);
    }
}

private void Placeholder_Show(object sender, EventArgs e)
{
    if (this.IsEmpty())
    {
        this._valueIsSet = false;
        this.Text = this._placeholder;
        this.ForeColor = Color.Gray;
        this.Font = new Font("Segoe UI", 10.2F, FontStyle.Italic);
    }
}

然后,为文本框的KeyDown event添加事件处理程序:

private void customTextBox_KeyDown(object sender, KeyEventArgs e)
{
    this._valueIsSet = true;
}

最后,创建一个属性myText

public string myText
{
    get
    {
        return this._valueIsSet ? this.Text : null;
    }
}

答案 1 :(得分:0)

您可以在TextBox上设置一个不会影响Text属性的提示文本。有关详细信息,请参阅EM_SETCUEBANNER

在表单上定义以下内容

Private Sub CommandButton1_Click()

     Dim Country As String, Name As String, Surname As String, Race As String
     Worksheets("form").Select

     Country = Range("B4")
     Name = Range("B6")
     Surname = Range("B7")
     Race = Range("B13")

     Worksheets("data").Select
     Worksheets("data").Range("A1").Select
     If Worksheets("data").Range("A1").Offset(1, 0) <> "" Then
          Worksheets("data").Range("A1").End(xlDown).Select
     End If

     ActiveCell.Offset(1, 0).Select
     ActiveCell.Value = Country
     ActiveCell.Offset(0, 1).Select
     ActiveCell.Value = Name
     ActiveCell.Offset(0, 1).Select
     ActiveCell.Value = Surname
     ActiveCell.Offset(0, 1).Select
     ActiveCell.Value = Race

     Worksheets("form").Select
     Worksheets("form").Range("A4").Select
End Sub

然后在表单加载

private const int EM_SETCUEBANNER = 0x1501;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)]string lParam);