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

Boa*_*rdy 129 c# wpf placeholder

我正在寻找一种方法来将占位符文本添加到文本框中,就像在html5中使用文本框一样.

即如果文本框没有文本,则添加文本Enter some text here,当用户点击它时,占位符文本消失并允许用户输入自己的文本,如果文本框失去焦点但仍然没有文本,则占位符为添加回文本框.

小智 84

你可以使用它,它对我有用,是一个非常简单的解决方案.

    <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>
Run Code Online (Sandbox Code Playgroud)

用法:

<TextBox Style="{StaticResource placeHolder}" Tag="Name of customer" Width="150" Height="24"/>
Run Code Online (Sandbox Code Playgroud)

  • 对焦点问题添加:`<ControlTemplate.Triggers> <Trigger Property ="IsFocused"Value ="True"> <Setter Property ="FocusManager.FocusedElement"TargetName ="textSource"Value ="{Binding RelativeSource = {RelativeSource Self} }"/> </ Trigger> </ControlTemplate.Triggers>` (6认同)
  • 我在哪里添加这个? (4认同)
  • @Sachin 我已经修复了我的 MaxLenght 属性。问题是 1 个文本框被 2 个文本框替换。一种用于输入,一种用于占位符。要修复损坏的属性,您只需将它们添加到第一个文本框,如下所示: `&lt;TextBox Text="{Binding Path=Text,relativeSource=RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="textSource “背景=“透明”Panel.ZIndex =“2”MaxLength =“{TemplateBinding MaxLength}”/&gt;`。在您的情况下,您可能需要添加 `AcceptsReturn="{TemplateBinding AcceptsReturn}"` (2认同)
  • 是的,**非常**简单...:^ (2认同)

Exc*_*Cat 76

这不是这样的事情:

Textbox myTxtbx = new Textbox();
myTxtbx.Text = "Enter text here...";

myTxtbx.GotFocus += GotFocus.EventHandle(RemoveText);
myTxtbx.LostFocus += LostFocus.EventHandle(AddText);

public void RemoveText(object sender, EventArgs e)
{
    if (myTxtbx.Text == "Enter text here...") 
    {
     myTxtbx.Text = "";
    }
}

public void AddText(object sender, EventArgs e)
{
    if (string.IsNullOrWhiteSpace(myTxtbx.Text))
        myTxtbx.Text = "Enter text here...";
}
Run Code Online (Sandbox Code Playgroud)

多数民众赞成只是伪代码,但概念就在那里.

  • 这将工作但如果文本框值绑定到源,那么您可能有问题. (5认同)
  • 谢谢,我希望有某种 XAML 可用于创建占位符。感谢您的帮助 (2认同)
  • `RemoveText`和`AddText`方法应该是`public void`,缺少**void**.正如@BibaswannBandyopadhyay所说,`RemoveText`方法可能是这样的:`if(myTxtbx.Text =="在这里输入文字......"){myTxtbx.Text ="";} (2认同)

Abd*_*eer 44

除了处理焦点输入和焦点离开事件以设置和删除占位符文本之外,还可以使用Windows SendMessage函数将 EM_SETCUEBANNER消息发送到我们的文本框以便为我们完成工作.

这可以通过两个简单的步骤完成.首先,我们需要公开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);
Run Code Online (Sandbox Code Playgroud)

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

SendMessage(textBox1.Handle, EM_SETCUEBANNER, 0, "Username");
SendMessage(textBox2.Handle, EM_SETCUEBANNER, 0, "Password");
Run Code Online (Sandbox Code Playgroud)

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

  • 注意:此**不适用于WPF**.请参阅:http://stackoverflow.com/questions/5054872/system-windows-controls-textbox-handle (8认同)
  • 这里是最佳答案,但是**注意** Form_Load 太早了,我必须等到 Form_Shown 才能工作。 (2认同)

小智 17

将此类添加到您的项目中并构建解决方案.单击Visual Studio上的工具箱,您将看到一个名为PlaceholderTextBox的新文本框组件.删除表单设计上的当前文本框,并替换为PlaceHolderTextBox.

在此输入图像描述

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

public class PlaceHolderTextBox : TextBox
{

    bool isPlaceHolder = true;
    string _placeHolderText;
    public string PlaceHolderText
    {
        get { return _placeHolderText; }
        set
        {
            _placeHolderText = value;
            setPlaceholder();
        }
    }

    public new string Text
    {
        get => isPlaceHolder ? string.Empty : base.Text;
        set => base.Text = value;
    }

    //when the control loses focus, the placeholder is shown
    private void setPlaceholder()
    {
        if (string.IsNullOrEmpty(base.Text))
        {
            base.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)
        {
            base.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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 当某些其他控件作用于"Text"属性的值(例如,用于过滤列表的文本框)时,占位符将用于过滤.占位符值只应用于显示,因此暂时替换"Text"属性不是一个好主意. (10认同)
  • 整洁的解决方案,我喜欢它。我会在类的顶部添加这些使用,以使其工作:`using System; 使用 System.Drawing;使用 System.Windows.Forms;` 谢谢! (2认同)

小智 14

这不是我的代码,但是我经常使用它并且它非常完美......仅限XAML

<TextBox x:Name="Textbox" Height="23" Margin="0,17,18.8,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" HorizontalAlignment="Right" ></TextBox>

<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>
Run Code Online (Sandbox Code Playgroud)

  • 工作起来就像一个魅力,如果您通过将“DataTrigger”替换为以下“MultiDataTrigger”来向 IsFocused 添加触发器,以我的拙见,它的效果会更好:“&lt;MultiDataTrigger&gt;&lt;MultiDataTrigger.Conditions&gt;&lt;Condition Binding="{ Binding IsFocused, ElementName=Textbox}" Value="false" /&gt;&lt;Condition Binding="{Binding Text, ElementName=Textbox}" Value="" /&gt;&lt;/MultiDataTrigger.Conditions&gt;&lt;MultiDataTrigger.Setters&gt; &lt;Setter Property= “可见性”值=“Visible”/&gt;&lt;/MultiDataTrigger.Setters&gt;&lt;/MultiDataTrigger&gt;` (2认同)

Dbl*_*Dbl 5

救援的附属物:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

<TextBox Text="hi" local:TextboxExtensions.Placeholder="Hello there"></TextBox>
Run Code Online (Sandbox Code Playgroud)


Vit*_*mel 5

基于 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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Gab*_*uci 5

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

所以这是WinForms的另一个解决方案.它覆盖Label在控件的顶部,仅在用户开始键入时消失.

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

像这样使用它:

SetPlaceholder(txtSearch, "Type what you're searching for");
Run Code Online (Sandbox Code Playgroud)

这是方法:

/// <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;
}
Run Code Online (Sandbox Code Playgroud)


syn*_*kro 5

我知道这是一个旧线程,但 .NET Core 和 .NET 5.0 已经实现了该TextBox.PlaceholderText属性。

https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.textbox.placeholdertext?view=net-5.0