显示“此处键入... ”,直到用户将文本输入TextBox
,这是众所周知的可用性功能。如何在C#中实现此功能?
我的想法是覆盖OnTextChanged
,但处理“在此输入”的文本更改的逻辑有点棘手......
在初始化时显示“在此输入”并在第一次输入时将其删除很容易,但我想在每次输入的文本变空时显示消息。
答案 0 :(得分:36)
对我有用的东西:
this.waterMarkActive = true;
this.textBox.ForeColor = Color.Gray;
this.textBox.Text = "Type here";
this.textBox.GotFocus += (source, e) =>
{
if (this.waterMarkActive)
{
this.waterMarkActive = false;
this.textBox.Text = "";
this.textBox.ForeColor = Color.Black;
}
};
this.textBox.LostFocus += (source, e) =>
{
if (!this.waterMarkActive && string.IsNullOrEmpty(this.textBox.Text))
{
this.waterMarkActive = true;
this.textBox.Text = "Type here";
this.textBox.ForeColor = Color.Gray;
}
};
其中bool waterMarkActive
是类成员变量,textBox
是TextBox
。这可能应该被封装了:)这种方法可能存在一些问题,但我目前还没有意识到这一点。
我最近发现Windows支持文本框中的水印;它们被称为提示横幅(见here)。它很容易实现:
// Within your class or scoped in a more appropriate location:
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
// In your constructor or somewhere more suitable:
SendMessage(textBox.Handle, 0x1501, 1, "Please type here.");
其中textBox
是TextBox
的实例,0x1501
是Windows消息EM_SETCUEBANNER
的代码,wParam
可能是TRUE
}(非零)或FALSE
(零),lParam
是您要显示的水印。 wParam
表示何时应显示提示横幅;如果设置为TRUE
,则即使控件具有焦点,也会显示提示横幅。
答案 1 :(得分:24)
答案 2 :(得分:8)
基于@Pooven的回答(谢谢!),我创建了这个类。适合我。
/// <summary>
/// A textbox that supports a watermak hint.
/// </summary>
public class WatermarkTextBox : TextBox
{
/// <summary>
/// The text that will be presented as the watermak hint
/// </summary>
private string _watermarkText = "Type here";
/// <summary>
/// Gets or Sets the text that will be presented as the watermak hint
/// </summary>
public string WatermarkText
{
get { return _watermarkText; }
set { _watermarkText = value; }
}
/// <summary>
/// Whether watermark effect is enabled or not
/// </summary>
private bool _watermarkActive = true;
/// <summary>
/// Gets or Sets whether watermark effect is enabled or not
/// </summary>
public bool WatermarkActive
{
get { return _watermarkActive; }
set { _watermarkActive = value; }
}
/// <summary>
/// Create a new TextBox that supports watermak hint
/// </summary>
public WatermarkTextBox()
{
this._watermarkActive = true;
this.Text = _watermarkText;
this.ForeColor = Color.Gray;
GotFocus += (source, e) =>
{
RemoveWatermak();
};
LostFocus += (source, e) =>
{
ApplyWatermark();
};
}
/// <summary>
/// Remove watermark from the textbox
/// </summary>
public void RemoveWatermak()
{
if (this._watermarkActive)
{
this._watermarkActive = false;
this.Text = "";
this.ForeColor = Color.Black;
}
}
/// <summary>
/// Applywatermak immediately
/// </summary>
public void ApplyWatermark()
{
if (!this._watermarkActive && string.IsNullOrEmpty(this.Text)
|| ForeColor == Color.Gray )
{
this._watermarkActive = true;
this.Text = _watermarkText;
this.ForeColor = Color.Gray;
}
}
/// <summary>
/// Apply watermak to the textbox.
/// </summary>
/// <param name="newText">Text to apply</param>
public void ApplyWatermark(string newText)
{
WatermarkText = newText;
ApplyWatermark();
}
}
答案 3 :(得分:4)
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)]string lParam);
const int EM_SETCUEBANNER = 0x1501;
public Form1()
{
InitializeComponent();
SendMessage(textBox1.Handle, EM_SETCUEBANNER, 1, "Username");
SendMessage(textBox2.Handle, EM_SETCUEBANNER, 1, "Password");
}
答案 4 :(得分:3)
我刚开始学习C#本学期所以我不是专家,但这对我有用: (这是使用Windows窗体)
private void Form1_Load(object sender, EventArgs e)
{
textBox1.SelectionStart = 0; //This keeps the text
textBox1.SelectionLength = 0; //from being highlighted
textBox1.ForeColor = Color.Gray;
}
private void textBox_MouseMove(object sender, MouseEventArgs e)
{
Cursor.Current = Cursors.IBeam; //Without this the mouse pointer shows busy
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (textBox1.Text.Equals("Type here...") == true)
{
textBox1.Text = "";
textBox1.ForeColor = Color.Black;
}
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (textBox1.Text.Equals(null) == true || textBox1.Text.Equals("") == true)
{
textBox1.Text = "Type here...";
textBox1.ForeColor = Color.Gray;
}
}
答案 5 :(得分:1)
处理丢失的焦点事件,如果属性Text为空,请使用默认字符串填充它。
答案 6 :(得分:1)
如果这是ASP.NET(而不是winforms),你可以这样做:
如果您使用的是jQuery,请将其添加到您的文档中(或者初始化您的页面):
var $textbox = $("textbox selector"); // assumes you select a single text box
if ($textbox.val() == "") {
$textbox.val("Type here to...");
$textbox.one('focus', function() {
$(this).attr('value', '');
});
}
如果要选择多个文本框,则需要进行一些小的重构(将if语句放在元素中的每个文本框中)。
答案 7 :(得分:1)
在C#的最后一个版本中,TextBox具有PlaceholderText属性,它可以完成所有工作。所以你只需要设置&#34;在这里输入...&#34;作为这个属性的价值。
答案 8 :(得分:0)
您可以在文本框背景中绘制字符串“在此处输入”,直到它为空
答案 9 :(得分:0)
如果这是针对ASP.NET的,那么您可以尝试TextBoxWatermark。
如果这是针对Windows窗体的,则已在SO中回复here。
答案 10 :(得分:0)
为什么要使用OnTextChanged? 当TextBox获得焦点时,我建议删除文本“在这里输入”。 当控件失去焦点且未输入任何文本时,您可以再次显示文本。
结果相同,不需要棘手的逻辑。
答案 11 :(得分:0)
生成与HTML WATERMARK类似的输出
这是我的文本框“水印”或“预览”文本的代码 - 效果很好!使用Windows窗体应用程序。
注意:此示例有3个文本框,每个文本框分别具有“鼠标离开”事件的方法和“鼠标输入”事件。
private void textBoxFav_Leave(object sender, EventArgs e) {
TextBox textbox = (TextBox)sender;
if (String.IsNullOrWhiteSpace(textbox.Text)) {
textbox.ForeColor = Color.Gray;
if (textbox.Name == "textBoxFavFood") {
textbox.Text = "Favorite Food";
}
else if (textbox.Name == "textBoxFavDrink") {
textbox.Text = "Favorite Drink";
}
else if (textbox.Name == "textBoxFavDesert") {
textbox.Text = "Favorite Desert";
}
}
else {
textbox.ForeColor = Color.Black;
}
}
private void textBoxFav_Enter(object sender, EventArgs e) {
TextBox textbox = (TextBox)sender;
if (textbox.Text == "Favorite Food" || textbox.Text == "Favorite Drink" || textbox.Text == "Favorite Desert") {
textbox.Text = "";
textbox.ForeColor = Color.Black;
}
}
答案 12 :(得分:0)
如果你想避免控制调整大小问题和数据绑定问题并使代码更简单(好吧,这是有问题的),你可以使用标签并切换它的可见性。然后
private void FilterComboBox_GotFocus(object sender, EventArgs e)
{
FilterWatermarkLabel.Visible = false;
}
private void FilterComboBox_LostFocus(object sender, EventArgs e)
{
if (!FilterWatermarkLabel.Visible && string.IsNullOrEmpty(FilterComboBox.Text))
{
FilterWatermarkLabel.Visible = true;
}
}
图像的另一种方法也避免了数据绑定问题 https://msdn.microsoft.com/en-us/library/bb613590(v=vs.100).aspx
答案 13 :(得分:0)
基于@ Joel的回答。我修了他的课(感谢基地!)
/// <summary>
/// A textbox that supports a watermak hint.
/// Based on: https://stackoverflow.com/a/15232752
/// </summary>
public class WatermarkTextBox : TextBox
{
/// <summary>
/// The text that will be presented as the watermak hint
/// </summary>
private string _watermarkText;
/// <summary>
/// Gets or Sets the text that will be presented as the watermak hint
/// </summary>
public string WatermarkText
{
get { return _watermarkText; }
set { _watermarkText = value; }
}
/// <summary>
/// Whether watermark effect is enabled or not
/// </summary>
private bool _watermarkActive;
/// <summary>
/// Gets or Sets whether watermark effect is enabled or not
/// </summary>
public bool WatermarkActive
{
get { return _watermarkActive; }
set { _watermarkActive = value; }
}
/// <summary>
/// Create a new TextBox that supports watermak hint
/// </summary>
public WatermarkTextBox()
{
this.WatermarkActive = _watermarkActive;
this.Text = _watermarkText;
}
protected override void OnCreateControl()
{
base.OnCreateControl();
if (this.WatermarkActive)
CheckWatermark();
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
CheckWatermark();
}
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
CheckWatermark();
}
public void CheckWatermark()
{
if ((this.WatermarkActive) && String.IsNullOrWhiteSpace(this.Text))
{
ForeColor = Color.Gray;
this.Text = _watermarkText;
}
else if ((this.WatermarkActive) && (!String.IsNullOrWhiteSpace(this.Text)))
{
if (this.Text == _watermarkText)
this.Text = "";
ForeColor = Color.Black;
}
else
ForeColor = Color.Black;
}
}
答案 14 :(得分:0)
根据Ahmed Soliman Flasha的回答,使用以下课程:
public class TextBoxHint : TextBox
{
string _hint;
[Localizable(true)]
public string Hint
{
get { return _hint; }
set { _hint = value; OnHintChanged(); }
}
protected virtual void OnHintChanged()
{
SendMessage(this.Handle, EM_SETCUEBANNER, 1, _hint);
}
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);
}