将占位符文本添加到文本框

我正在寻找一种方法来添加占位符文本到一个文本框,就像你可以用HTML5中的文本框。

也就是说,如果文本框没有文本,那么它会在Enter some text here添加文本Enter some text here ,当用户点击它时占位符文本消失,并允许用户input自己的文本,如果文本框失去焦点,并且仍然没有文字然后占位符被添加回到文本框。

难道这不是这样的:

 Textbox myTxtbx = new Textbox(); myTxtbx.Text = "Enter text here..."; myTxtbx.GotFocus += GotFocus.EventHandle(RemoveText); myTxtbx.LostFocus += LostFocus.EventHandle(AddText); public RemoveText(object sender, EventArgs e) { myTxtbx.Text = ""; } public AddText(object sender, EventArgs e) { if(String.IsNullOrWhiteSpace(myTxtbx.Text)) myTxtbx.Text = "Enter text here..."; } 

这只是伪代码,但概念在那里。

你可以使用这个,这对我来说是非常简单的解决scheme。

  <Style x:Key="placeHolder" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TextBox}"> <Grid> <TextBox Text="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="textSource" Background="Transparent" Panel.ZIndex="2" /> <TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1"> <TextBox.Style> <Style TargetType="{x:Type TextBox}"> <Setter Property="Foreground" Value="Transparent"/> <Style.Triggers> <DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value=""> <Setter Property="Foreground" Value="LightGray"/> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> 

用法:

 <TextBox Style="{StaticResource placeHolder}" Tag="Name of customer" Width="150" Height="24"/> 

为了设置和删除占位符文本,可以使用Windows SendMessage函数将EM_SETCUEBANNER消息发送到我们的文本框来为我们完成工作,而不是处理焦点input和焦点离开事件。

这可以通过两个简单的步骤完成。 首先我们需要公开Windows SendMessage函数。

 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); 

然后只需使用我们的文本框的句柄EM_SETCUEBANNER的值和我们想要设置的文本调用方法。

 SendMessage(textBox1.Handle, EM_SETCUEBANNER, 0, "Username"); SendMessage(textBox2.Handle, EM_SETCUEBANNER, 0, "Password"); 

参考: 设置文本框的占位符文本(提示文本)

添加这个类你的项目,并build立你的解决scheme。 在Visual Studio上单击工具箱,您将看到一个名为PlaceholderTextBox的新文本框。 在表单devise中删除当前的文本框,并用PlaceHolderTextBoxreplace。

在这里输入图像说明

PlaceHolderTextBox有一个属性PlaceHolderText。 设置你想要的任何文本,并有美好的一天:)

 public class PlaceHolderTextBox : TextBox { bool isPlaceHolder = true; string _placeHolderText; public string PlaceHolderText { get { return _placeHolderText; } set { _placeHolderText = value; setPlaceholder(); } } //when the control loses focus, the placeholder is shown private void setPlaceholder() { if (string.IsNullOrEmpty(this.Text)) { this.Text = PlaceHolderText; this.ForeColor = Color.Gray; this.Font = new Font(this.Font, FontStyle.Italic); isPlaceHolder = true; } } //when the control is focused, the placeholder is removed private void removePlaceHolder() { if (isPlaceHolder) { this.Text = ""; this.ForeColor = System.Drawing.SystemColors.WindowText; this.Font = new Font(this.Font, FontStyle.Regular); isPlaceHolder = false; } } public PlaceHolderTextBox() { GotFocus += removePlaceHolder; LostFocus += setPlaceholder; } private void setPlaceholder(object sender, EventArgs e) { setPlaceholder(); } private void removePlaceHolder(object sender, EventArgs e) { removePlaceHolder(); } } 

附加属性的救援:

 public static class TextboxExtensions { public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.RegisterAttached( "Placeholder", typeof(string), typeof(TextboxExtensions), new PropertyMetadata(default(string), propertyChangedCallback: PlaceholderChanged)); private static void PlaceholderChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) { var tb = dependencyObject as TextBox; if(tb == null) return; tb.LostFocus -= OnLostFocus; tb.GotFocus -= OnGotFocus; if (args.NewValue != null) { tb.GotFocus += OnGotFocus; tb.LostFocus += OnLostFocus; } } private static void OnLostFocus(object sender, RoutedEventArgs routedEventArgs) { var tb = sender as TextBox; if (string.IsNullOrEmpty(tb.Text) || string.IsNullOrWhiteSpace(tb.Text)) { tb.Text = GetPlaceholder(tb); } } private static void OnGotFocus(object sender, RoutedEventArgs routedEventArgs) { var tb = sender as TextBox; var ph = GetPlaceholder(tb); if (tb.Text == ph) { tb.Text = string.Empty; } } [AttachedPropertyBrowsableForType(typeof(TextBox))] public static void SetPlaceholder(DependencyObject element, string value) { element.SetValue(PlaceholderProperty, value); } [AttachedPropertyBrowsableForType(typeof(TextBox))] public static string GetPlaceholder(DependencyObject element) { return (string) element.GetValue(PlaceholderProperty); } } 

用法:

 <TextBox Text="hi" local:TextboxExtensions.Placeholder="Hello there"></TextBox> 

你可以得到默认的Template ,通过叠加一个TextBlock修改它,并使用一个Style来添加触发器,隐藏并以正确的状态显示它。

这意味着你有一个button,允许你做一个动作,比如login或者其他的东西。 在执行操作之前,请检查文本框是否被填充。如果不是,将replace文本

  private void button_Click(object sender, EventArgs e) { string textBoxText = textBox.Text; if (String.IsNullOrWhiteSpace(textBoxText)) { textBox.Text = "Fill in the textbox"; } } private void textBox_Enter(object sender, EventArgs e) { TextBox currentTextbox = sender as TextBox; if (currentTextbox.Text == "Fill in the textbox") { currentTextbox.Text = ""; } } 

这是一种俗气,但检查文本的价值,你给它是最好的,我可以做atm,不是很好的C#获得更好的解决scheme。

基于ExceptionLimeCat的答案,一个改进:

 Color farbe; string ph = "Placeholder-Text"; private void Form1_Load(object sender, EventArgs e) { farbe = myTxtbx.ForeColor; myTxtbx.GotFocus += RemoveText; myTxtbx.LostFocus += AddText; myTxtbx.Text = ph; } public void RemoveText(object sender, EventArgs e) { myTxtbx.ForeColor = farbe; if (myTxtbx.Text == ph) myTxtbx.Text = ""; } public void AddText(object sender, EventArgs e) { if (String.IsNullOrWhiteSpace(myTxtbx.Text)) { myTxtbx.ForeColor = Color.Gray; myTxtbx.Text = ph; } } 

虽然使用EM_SETCUEBANNER消息可能是最简单的,但我不喜欢的是当控件获得焦点时,占位符文本消失。 当我填写表格时,这是我的宠物。 我必须点击它来记住该字段的用途。

所以这里是WinForms的另一个解决scheme。 它在控件之上叠加一个Label ,只有当用户开始input时才会消失。

这当然不是防弹的。 它接受任何Control ,但我只testing一个TextBox 。 可能需要修改才能使用某些控件。 该方法返回Label控件,以防在特定情况下需要修改它,但可能永远不需要。

像这样使用它:

 SetPlaceholder(txtSearch, "Type what you're searching for"); 

这里是方法:

  /// <summary> /// Sets placeholder text on a control (may not work for some controls) /// </summary> /// <param name="control">The control to set the placeholder on</param> /// <param name="text">The text to display as the placeholder</param> /// <returns>The newly-created placeholder Label</returns> public static Label SetPlaceholder(Control control, string text) { var placeholder = new Label { Text = text, Font = control.Font, ForeColor = Color.Gray, BackColor = Color.Transparent, Cursor = Cursors.IBeam, Margin = Padding.Empty, //get rid of the left margin that all labels have FlatStyle = FlatStyle.System, AutoSize = false, //Leave 1px on the left so we can see the blinking cursor Size = new Size(control.Size.Width - 1, control.Size.Height), Location = new Point(control.Location.X + 1, control.Location.Y) }; //when clicking on the label, pass focus to the control placeholder.Click += (sender, args) => { control.Focus(); }; //disappear when the user starts typing control.TextChanged += (sender, args) => { placeholder.Visible = string.IsNullOrEmpty(control.Text); }; //stay the same size/location as the control EventHandler updateSize = (sender, args) => { placeholder.Location = new Point(control.Location.X + 1, control.Location.Y); placeholder.Size = new Size(control.Size.Width - 1, control.Size.Height); }; control.SizeChanged += updateSize; control.LocationChanged += updateSize; control.Parent.Controls.Add(placeholder); placeholder.BringToFront(); return placeholder; } } 

我想出了一个适用于我的方法,但只是因为我愿意使用文本框名称作为占位符。 见下文。

 public TextBox employee = new TextBox(); private void InitializeHomeComponent() { // //employee // this.employee.Name = "Caller Name"; this.employee.Text = "Caller Name"; this.employee.BackColor = System.Drawing.SystemColors.InactiveBorder; this.employee.Location = new System.Drawing.Point(5, 160); this.employee.Size = new System.Drawing.Size(190, 30); this.employee.TabStop = false; this.Controls.Add(employee); // I loop through all of my textboxes giving them the same function foreach (Control C in this.Controls) { if (C.GetType() == typeof(System.Windows.Forms.TextBox)) { C.GotFocus += g_GotFocus; C.LostFocus += g_LostFocus; } } } private void g_GotFocus(object sender, EventArgs e) { var tbox = sender as TextBox; tbox.Text = ""; } private void g_LostFocus(object sender, EventArgs e) { var tbox = sender as TextBox; if (tbox.Text == "") { tbox.Text = tbox.Name; } } 

这不是我的代码,但我使用它很多,它的作品完美… XAML只

 <TextBox x:Name="Textbox" Height="23" Margin="0,17,18.8,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" HorizontalAlignment="Right" <TextBlock x:Name="Placeholder" IsHitTestVisible="False" TextWrapping="Wrap" Text="Placeholder Text" VerticalAlignment="Top" Margin="0,20,298.8,0" Foreground="DarkGray" HorizontalAlignment="Right" Width="214"> <TextBlock.Style> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Visibility" Value="Collapsed"/> <Style.Triggers> <DataTrigger Binding="{Binding Text, ElementName=Textbox}" Value=""> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock> 
 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; namespace App_name { public class CustomTextBox : TextBox { private string Text_ = ""; public CustomTextBox() : base() {} public string setHint { get { return Text_; } set { Text_ = value; } } protected override void OnGotFocus(RoutedEventArgs e) { base.OnGotFocus(e); if (Text_.Equals(this.Text)) this.Clear(); } protected override void OnLostFocus(RoutedEventArgs e) { base.OnLostFocus(e); if (String.IsNullOrWhiteSpace(this.Text)) this.Text = Text_; } } } > xmlns:local="clr-namespace:app_name" > <local:CustomTextBox > x:Name="id_number_txt" > Width="240px" > Height="auto"/> 

试试下面的代码:

 <TextBox x:Name="InvoiceDate" Text="" Width="300" TextAlignment="Left" Height="30" Grid.Row="0" Grid.Column="3" Grid.ColumnSpan="2" /> <TextBlock IsHitTestVisible="False" Text="Men att läsa" Width="300" TextAlignment="Left" Height="30" Grid.Row="0" Grid.Column="3" Grid.ColumnSpan="2" Padding="5, 5, 5, 5" Foreground="LightGray"> <TextBlock.Style> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Visibility" Value="Collapsed"/> <Style.Triggers> <DataTrigger Binding="{Binding Text, ElementName=InvoiceDate}" Value=""> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> <DataTrigger Binding="{Binding ElementName=InvoiceDate, Path=IsFocused}" Value="True"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock> 

txtUsuario.Attributes.Add(“placeholder”,“Texto”);

你也可以这样做,当鼠标点击,让我们假设你的占位符文本是“User_Name”

  private void textBox1_MouseClick(object sender, MouseEventArgs e) { if(textBox1.Text == "User_Name") textBox1.Text = ""; } 
  public void Initialize() { SetPlaceHolder(loginTextBox, " Логин "); SetPlaceHolder(passwordTextBox, " Пароль "); } public void SetPlaceHolder(Control control, string PlaceHolderText) { control.Text = PlaceHolderText; control.GotFocus += delegate(object sender, EventArgs args) { if (control.Text == PlaceHolderText) { control.Text = ""; } }; control.LostFocus += delegate(object sender, EventArgs args){ if (control.Text.Length == 0) { control.Text = PlaceHolderText; } }; } 

我没有使用TextBox的.Text属性,而是用占位符叠加了一个TextBlock。 我无法使用.Text属性,因为这绑定到一个事件。

XAML:

 <Canvas Name="placeHolderCanvas"> <TextBox AcceptsReturn="True" Name="txtAddress" Height="50" Width="{Binding ActualWidth, ElementName=placeHolderCanvas}" Tag="Please enter your address"/> </Canvas> 

VB.NET

 Public Shared Sub InitPlaceholder(canvas As Canvas) Dim txt As TextBox = canvas.Children.OfType(Of TextBox).First() Dim placeHolderLabel = New TextBlock() With {.Text = txt.Tag, .Foreground = New SolidColorBrush(Color.FromRgb(&H77, &H77, &H77)), .IsHitTestVisible = False} Canvas.SetLeft(placeHolderLabel, 3) Canvas.SetTop(placeHolderLabel, 1) canvas.Children.Add(placeHolderLabel) AddHandler txt.TextChanged, Sub() placeHolderLabel.Visibility = If(txt.Text = "", Visibility.Visible, Visibility.Hidden) End Sub 

结果: 在这里输入图像说明

你也可以这样试试

调用该函数

 TextboxPlaceHolder(this.textBox1, "YourPlaceHolder"); 

写这个函数

 private void TextboxPlaceHolder(Control control, string PlaceHolderText) { control.Text = PlaceHolderText; control.GotFocus += delegate (object sender, EventArgs args) { if (cusmode == false) { control.Text = control.Text == PlaceHolderText ? string.Empty : control.Text; //IF Focus TextBox forecolor Black control.ForeColor = Color.Black; } }; control.LostFocus += delegate (object sender, EventArgs args) { if (string.IsNullOrWhiteSpace(control.Text) == true) { control.Text = PlaceHolderText; //If not focus TextBox forecolor to gray control.ForeColor = Color.Gray; } }; } 

在这里我带着这个由@Kemal Karadag启发的解决scheme。

我注意到,这里发布的每个解决scheme都依赖于重点,

虽然我希望占位符是Google Chrome中标准HTML占位符的确切克隆。

当箱子聚焦时,而不是隐藏/显示占位符,

我根据框的文本长度隐藏/显示占位符:

如果该框为空,则显示占位符,如果在框中键入,则占位符消失。

由于它是从一个标准的TextBoxinheritance的,你可以在你的工具箱中find它!

 using System; using System.Drawing; using System.Windows.Forms; public class PlaceHolderTextBox : TextBox { private bool isPlaceHolder = true; private string placeHolderText; public string PlaceHolderText { get { return placeHolderText; } set { placeHolderText = value; SetPlaceholder(); } } public PlaceHolderTextBox() { TextChanged += OnTextChanged; } private void SetPlaceholder() { if (!isPlaceHolder) { this.Text = placeHolderText; this.ForeColor = Color.Gray; isPlaceHolder = true; } } private void RemovePlaceHolder() { if (isPlaceHolder) { this.Text = this.Text[0].ToString(); // Remove placeHolder text, but keep the character we just entered this.Select(1, 0); // Place the caret after the character we just entered this.ForeColor = System.Drawing.SystemColors.WindowText; isPlaceHolder = false; } } private void OnTextChanged(object sender, EventArgs e) { if (this.Text.Length == 0) { SetPlaceholder(); } else { RemovePlaceHolder(); } } }