TextBox 中的真实提示 Visual Studio C#
Real Hint in TextBox Visual Studio C#
我目前正在使用 C# 在 Visual Studio 上制作 Windows 表单应用程序,我正在尝试找到一种方法来获得真正的 提示 .
我在网上找到了很多关于如何在那里预设一些文本的答案,一些示例甚至显示了如何将文本变灰以看起来像占位符,但这不是我要找的。
我想要一个灰色的文本,您无需退格即可在其中键入内容。所以我希望它表现得像一个 HTML 占位符 就像堆栈溢出上的 "Search Q&A" 搜索栏。
有没有简单的方法可以做到这一点,比如在 Visual Studio 上的设计器中配置文本框的 属性?
您是否尝试过在文本框上重叠标签?
在文本框按键事件中,您可以检查 textbox.text 的长度并设置标签。
关于按键事件..
MyLabel.Visible = String.IsNullOrEmpty(MyTextBox.Text);
当然,您可能希望设置标签的默认文本并将其变灰。
问题在于您的表单是否可以调整大小。
您想要实现的不是 windows 表单的原生内容。
这个呢
private bool hasTextBeenTyped;
private void Form1_Load(object sender, EventArgs e)
{
this.ActiveControl = label1;
textBox1.ForeColor = Color.LightGray;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
hasTextBeenTyped = !String.IsNullOrEmpty(textBox1.Text);
if (hasTextBeenTyped)
{
textBox1.ForeColor = Color.Black;
}
}
private void textBox1_Click(object sender, EventArgs e)
{
if (!hasTextBeenTyped)
{
textBox1.Text = "";
}
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
hasTextBeenTyped = true;
}
this.ActiveControl = label1;最初只是为了将焦点从文本框上移开。如果其他东西已经做了,不用担心那一行。
请看一下我的ControlHintManager class, ControlHintInfo type and ControlHintType枚举。它们是用 Vb.Net 编写的,但您可以通过分析源代码获得想法,或编译库以在您的 C# 项目中使用它,而无需任何更多努力。
我的解决方案比您提到的 Whosebugs 提示具有更好的行为,考虑到当控件离开焦点时,如果字符串为空,则应恢复提示文本。
用法非常友好:
ControlHintInfo hint1 =
new ControlHintInfo("I'm a hint text.", font (or nul), Color.Gray,
ControlHintType.Persistent);
ControlHintManager.SetHint(TextBox1, hint1);
要自己实现,一种方法是使用 EM_SETCUEBANNER
消息调用 Win32 SendMessage
函数,但是,这会产生过于基本的提示,行为不佳,不推荐,
因此,实现此目的的正确方法是自己控制编辑控件文本,处理 Control.HandleCreated
、Control.Enter
、Control.Leave
、Control.MouseDown
, Control.KeyDown
和 Control.Disposed
事件(如您在我的链接源代码中所见)。
只需使用一个对象来跟踪控件的状态(前景色、文本和可选的字体),然后适当地使用提到的事件处理程序来设置或恢复文本和颜色。
这是链接 url 最重要代码的在线 C# 翻译,如果这有助于您更好地理解它:
private static void Control_HandleCreated(object sender, EventArgs e) {
InstanceControlHintFields();
Control ctrl = (Control)sender;
ControlHintInfo hintInfo = controlHintsB(ctrl);
SetProperties(ctrl, hintInfo);
}
private static void Control_Enter(object sender, EventArgs e) {
InstanceControlHintFields();
Control ctrl = (Control)sender;
string ctrlText = ctrl.Text;
ControlHintInfo ctrlDefaults = controlHintsDefaults(ctrl);
ControlHintInfo hintInfo = controlHintsB(ctrl);
switch (hintInfo.HintType) {
case ControlHintType.Normal:
if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
RestoreProperties(ctrl, ctrlDefaults);
}
break;
}
}
private static void Control_Leave(object sender, EventArgs e) {
InstanceControlHintFields();
Control ctrl = (Control)sender;
string ctrlText = ctrl.Text;
ControlHintInfo ctrlDefaults = controlHintsDefaults(ctrl);
ControlHintInfo hintInfo = controlHintsB(ctrl);
switch (hintInfo.HintType) {
case ControlHintType.Normal:
if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
RestoreProperties(ctrl, ctrlDefaults);
} else if (string.IsNullOrEmpty(ctrlText)) {
SetProperties(ctrl, hintInfo);
}
break;
case ControlHintType.Persistent:
if (string.IsNullOrEmpty(ctrlText)) {
SetProperties(ctrl, hintInfo);
}
break;
}
}
private static void Control_MouseDown(object sender, MouseEventArgs e) {
InstanceControlHintFields();
Control ctrl = (Control)sender;
string ctrlText = ctrl.Text;
ControlHintInfo hintInfo = controlHintsB(ctrl);
switch (hintInfo.HintType) {
case ControlHintType.Persistent:
if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
// Get the 'Select' control's method (if exist).
MethodInfo method = sender.GetType.GetMethod("Select", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, {
typeof(int),
typeof(int)
}, null);
if ((method != null)) {
// Select the zero length.
method.Invoke(ctrl, new object[] {
0,
0
});
}
}
break;
}
}
private static void Control_KeyDown(object sender, KeyEventArgs e) {
Control ctrl = (Control)sender;
string ctrlText = ctrl.Text;
ControlHintInfo ctrlDefaults = controlHintsDefaults(ctrl);
ControlHintInfo hintInfo = controlHintsB(ctrl);
switch (hintInfo.HintType) {
case ControlHintType.Persistent:
if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
RestoreProperties(ctrl, ctrlDefaults);
} else if (string.IsNullOrEmpty(ctrlText)) {
RestoreProperties(ctrl, ctrlDefaults, skipProperties: { "Text" });
}
break;
case ControlHintType.Normal:
if (string.IsNullOrEmpty(ctrlText)) {
RestoreProperties(ctrl, ctrlDefaults);
}
break;
}
}
private static void Control_Disposed(object sender, EventArgs e) {
RemoveHint((Control)sender);
}
PS:基于Reflection,支持更多种类的控件。
这可能是最丑陋的代码,但我认为您可以改进它。
下面的 class 只是标准 TextBox
的扩展
class PHTextBox : System.Windows.Forms.TextBox
{
System.Drawing.Color DefaultColor;
public string PlaceHolderText {get;set;}
public PHTextBox(string placeholdertext)
{
// get default color of text
DefaultColor = this.ForeColor;
// Add event handler for when the control gets focus
this.GotFocus += (object sender, EventArgs e) =>
{
this.Text = String.Empty;
this.ForeColor = DefaultColor;
};
// add event handling when focus is lost
this.LostFocus += (Object sender, EventArgs e) => {
if (String.IsNullOrEmpty(this.Text) || this.Text == PlaceHolderText)
{
this.ForeColor = System.Drawing.Color.Gray;
this.Text = PlaceHolderText;
}
else
{
this.ForeColor = DefaultColor;
}
};
if (!string.IsNullOrEmpty(placeholdertext))
{
// change style
this.ForeColor = System.Drawing.Color.Gray;
// Add text
PlaceHolderText = placeholdertext;
this.Text = placeholdertext;
}
}
}
Copy/paste 到名为 PHTextBox.cs.
的新 cs 文件
请您的图形设计师添加一个文本框。
转到设计器并更改文本框的 instition 行,如下所示:
现在编译,但在此之前,请确保文本框不是第一个获得焦点的元素。为此添加按钮。
我知道这是一个老问题;但是我正在寻找一种方法,我发现我的答案是最佳答案 在 TextBox
中显示提示文本:
1) 创建一个 class .cs
文件例如调用 MyExtensions.cs
具有 命名空间 例如调用 'Extensions'.
2)在TextBox
中创建一个名为Init(string prompt)[=的方法53=] 获取要在 TextBox
.
中显示的提示文本
3)废话不多说了,把MyExtensions.cs
剩下的代码给大家(完整代码):
MyExtensions.cs
using System.Drawing;
using System.Windows.Forms;
namespace Extensions
{
public static class MyExtensions
{
public static void Init(this TextBox textBox, string prompt)
{
textBox.Text = prompt;
bool wma = true;
textBox.ForeColor = Color.Gray;
textBox.GotFocus += (source, ex) =>
{
if (((TextBox)source).ForeColor == Color.Black)
return;
if (wma)
{
wma = false;
textBox.Text = "";
textBox.ForeColor = Color.Black;
}
};
textBox.LostFocus += (source, ex) =>
{
TextBox t = ((TextBox)source);
if (t.Text.Length == 0)
{
t.Text = prompt;
t.ForeColor = Color.Gray;
return;
}
if (!wma && string.IsNullOrEmpty(textBox.Text))
{
wma = true;
textBox.Text = prompt;
textBox.ForeColor = Color.Gray;
}
};
textBox.TextChanged += (source, ex) =>
{
if (((TextBox)source).Text.Length > 0)
{
textBox.ForeColor = Color.Black;
}
};
}
}
}
现在假设您有三个 TextBox
:tbUsername
、tbPassword
、tbConfirm
:
在您的 Form_Load(object sender, EventArgs e) 方法中初始化您的三个 TextBox,使其具有适当的 Prompt Text Messages:
using Extensions;
namespace MyApp{
public partial class Form1 : Form{
private void Form1_Load(object sender,
EventArgs e){
tbUsername.Init("Type a username");
tbPassword.Init("Type a password");
tbConfirm.Init("Confirm your password");
}
}
}
尽情享受吧! :)
我目前正在使用 C# 在 Visual Studio 上制作 Windows 表单应用程序,我正在尝试找到一种方法来获得真正的 提示 .
我在网上找到了很多关于如何在那里预设一些文本的答案,一些示例甚至显示了如何将文本变灰以看起来像占位符,但这不是我要找的。
我想要一个灰色的文本,您无需退格即可在其中键入内容。所以我希望它表现得像一个 HTML 占位符 就像堆栈溢出上的 "Search Q&A" 搜索栏。
有没有简单的方法可以做到这一点,比如在 Visual Studio 上的设计器中配置文本框的 属性?
您是否尝试过在文本框上重叠标签?
在文本框按键事件中,您可以检查 textbox.text 的长度并设置标签。
关于按键事件..
MyLabel.Visible = String.IsNullOrEmpty(MyTextBox.Text);
当然,您可能希望设置标签的默认文本并将其变灰。
问题在于您的表单是否可以调整大小。
您想要实现的不是 windows 表单的原生内容。
这个呢
private bool hasTextBeenTyped;
private void Form1_Load(object sender, EventArgs e)
{
this.ActiveControl = label1;
textBox1.ForeColor = Color.LightGray;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
hasTextBeenTyped = !String.IsNullOrEmpty(textBox1.Text);
if (hasTextBeenTyped)
{
textBox1.ForeColor = Color.Black;
}
}
private void textBox1_Click(object sender, EventArgs e)
{
if (!hasTextBeenTyped)
{
textBox1.Text = "";
}
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
hasTextBeenTyped = true;
}
this.ActiveControl = label1;最初只是为了将焦点从文本框上移开。如果其他东西已经做了,不用担心那一行。
请看一下我的ControlHintManager class, ControlHintInfo type and ControlHintType枚举。它们是用 Vb.Net 编写的,但您可以通过分析源代码获得想法,或编译库以在您的 C# 项目中使用它,而无需任何更多努力。
我的解决方案比您提到的 Whosebugs 提示具有更好的行为,考虑到当控件离开焦点时,如果字符串为空,则应恢复提示文本。
用法非常友好:
ControlHintInfo hint1 =
new ControlHintInfo("I'm a hint text.", font (or nul), Color.Gray,
ControlHintType.Persistent);
ControlHintManager.SetHint(TextBox1, hint1);
要自己实现,一种方法是使用 EM_SETCUEBANNER
消息调用 Win32 SendMessage
函数,但是,这会产生过于基本的提示,行为不佳,不推荐,
因此,实现此目的的正确方法是自己控制编辑控件文本,处理 Control.HandleCreated
、Control.Enter
、Control.Leave
、Control.MouseDown
, Control.KeyDown
和 Control.Disposed
事件(如您在我的链接源代码中所见)。
只需使用一个对象来跟踪控件的状态(前景色、文本和可选的字体),然后适当地使用提到的事件处理程序来设置或恢复文本和颜色。
这是链接 url 最重要代码的在线 C# 翻译,如果这有助于您更好地理解它:
private static void Control_HandleCreated(object sender, EventArgs e) {
InstanceControlHintFields();
Control ctrl = (Control)sender;
ControlHintInfo hintInfo = controlHintsB(ctrl);
SetProperties(ctrl, hintInfo);
}
private static void Control_Enter(object sender, EventArgs e) {
InstanceControlHintFields();
Control ctrl = (Control)sender;
string ctrlText = ctrl.Text;
ControlHintInfo ctrlDefaults = controlHintsDefaults(ctrl);
ControlHintInfo hintInfo = controlHintsB(ctrl);
switch (hintInfo.HintType) {
case ControlHintType.Normal:
if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
RestoreProperties(ctrl, ctrlDefaults);
}
break;
}
}
private static void Control_Leave(object sender, EventArgs e) {
InstanceControlHintFields();
Control ctrl = (Control)sender;
string ctrlText = ctrl.Text;
ControlHintInfo ctrlDefaults = controlHintsDefaults(ctrl);
ControlHintInfo hintInfo = controlHintsB(ctrl);
switch (hintInfo.HintType) {
case ControlHintType.Normal:
if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
RestoreProperties(ctrl, ctrlDefaults);
} else if (string.IsNullOrEmpty(ctrlText)) {
SetProperties(ctrl, hintInfo);
}
break;
case ControlHintType.Persistent:
if (string.IsNullOrEmpty(ctrlText)) {
SetProperties(ctrl, hintInfo);
}
break;
}
}
private static void Control_MouseDown(object sender, MouseEventArgs e) {
InstanceControlHintFields();
Control ctrl = (Control)sender;
string ctrlText = ctrl.Text;
ControlHintInfo hintInfo = controlHintsB(ctrl);
switch (hintInfo.HintType) {
case ControlHintType.Persistent:
if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
// Get the 'Select' control's method (if exist).
MethodInfo method = sender.GetType.GetMethod("Select", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, {
typeof(int),
typeof(int)
}, null);
if ((method != null)) {
// Select the zero length.
method.Invoke(ctrl, new object[] {
0,
0
});
}
}
break;
}
}
private static void Control_KeyDown(object sender, KeyEventArgs e) {
Control ctrl = (Control)sender;
string ctrlText = ctrl.Text;
ControlHintInfo ctrlDefaults = controlHintsDefaults(ctrl);
ControlHintInfo hintInfo = controlHintsB(ctrl);
switch (hintInfo.HintType) {
case ControlHintType.Persistent:
if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
RestoreProperties(ctrl, ctrlDefaults);
} else if (string.IsNullOrEmpty(ctrlText)) {
RestoreProperties(ctrl, ctrlDefaults, skipProperties: { "Text" });
}
break;
case ControlHintType.Normal:
if (string.IsNullOrEmpty(ctrlText)) {
RestoreProperties(ctrl, ctrlDefaults);
}
break;
}
}
private static void Control_Disposed(object sender, EventArgs e) {
RemoveHint((Control)sender);
}
PS:基于Reflection,支持更多种类的控件。
这可能是最丑陋的代码,但我认为您可以改进它。
下面的 class 只是标准 TextBox
的扩展 class PHTextBox : System.Windows.Forms.TextBox
{
System.Drawing.Color DefaultColor;
public string PlaceHolderText {get;set;}
public PHTextBox(string placeholdertext)
{
// get default color of text
DefaultColor = this.ForeColor;
// Add event handler for when the control gets focus
this.GotFocus += (object sender, EventArgs e) =>
{
this.Text = String.Empty;
this.ForeColor = DefaultColor;
};
// add event handling when focus is lost
this.LostFocus += (Object sender, EventArgs e) => {
if (String.IsNullOrEmpty(this.Text) || this.Text == PlaceHolderText)
{
this.ForeColor = System.Drawing.Color.Gray;
this.Text = PlaceHolderText;
}
else
{
this.ForeColor = DefaultColor;
}
};
if (!string.IsNullOrEmpty(placeholdertext))
{
// change style
this.ForeColor = System.Drawing.Color.Gray;
// Add text
PlaceHolderText = placeholdertext;
this.Text = placeholdertext;
}
}
}
Copy/paste 到名为 PHTextBox.cs.
的新 cs 文件请您的图形设计师添加一个文本框。 转到设计器并更改文本框的 instition 行,如下所示:
现在编译,但在此之前,请确保文本框不是第一个获得焦点的元素。为此添加按钮。
我知道这是一个老问题;但是我正在寻找一种方法,我发现我的答案是最佳答案 在 TextBox
中显示提示文本:
1) 创建一个 class .cs
文件例如调用 MyExtensions.cs
具有 命名空间 例如调用 'Extensions'.
2)在TextBox
中创建一个名为Init(string prompt)[=的方法53=] 获取要在 TextBox
.
3)废话不多说了,把MyExtensions.cs
剩下的代码给大家(完整代码):
MyExtensions.cs
using System.Drawing;
using System.Windows.Forms;
namespace Extensions
{
public static class MyExtensions
{
public static void Init(this TextBox textBox, string prompt)
{
textBox.Text = prompt;
bool wma = true;
textBox.ForeColor = Color.Gray;
textBox.GotFocus += (source, ex) =>
{
if (((TextBox)source).ForeColor == Color.Black)
return;
if (wma)
{
wma = false;
textBox.Text = "";
textBox.ForeColor = Color.Black;
}
};
textBox.LostFocus += (source, ex) =>
{
TextBox t = ((TextBox)source);
if (t.Text.Length == 0)
{
t.Text = prompt;
t.ForeColor = Color.Gray;
return;
}
if (!wma && string.IsNullOrEmpty(textBox.Text))
{
wma = true;
textBox.Text = prompt;
textBox.ForeColor = Color.Gray;
}
};
textBox.TextChanged += (source, ex) =>
{
if (((TextBox)source).Text.Length > 0)
{
textBox.ForeColor = Color.Black;
}
};
}
}
}
现在假设您有三个 TextBox
:tbUsername
、tbPassword
、tbConfirm
:
在您的 Form_Load(object sender, EventArgs e) 方法中初始化您的三个 TextBox,使其具有适当的 Prompt Text Messages:
using Extensions;
namespace MyApp{
public partial class Form1 : Form{
private void Form1_Load(object sender,
EventArgs e){
tbUsername.Init("Type a username");
tbPassword.Init("Type a password");
tbConfirm.Init("Confirm your password");
}
}
}
尽情享受吧! :)