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


147

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

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


4
不要将Text属性用于占位符文本。它将干扰绑定。使用AdornerDecorator(msdn.microsoft.com/en-us/library/…
Pavel Voronin


5
只是FYI- 水印 aka 提示文本 aka 占位符文本 aka 提示横幅。所有这些术语都具有同义词的意图。
英国广播公司

Answers:


91

那不是仅仅是这样的事情:

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...";
}

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


谢谢,我期待有某种XAML可用于创建占位符。感谢您的帮助
-Boardy

1
我希望找到一种解决方案,将占位符文本保留在文本框中,直到用户输入文本为止。似乎那样会更好。
DROP TABLE用户

6
如果文本框值绑定到源,这将起作用,但是您可能有问题。
Pavel Voronin 2014年

1
这是一个很好的简单解决方案,唯一的问题是,即使在输入文本之后,如果用户再次单击文本框(例如,添加更多文本或删除一些字符),整个文本框也将失去输入的值
Bibaswann Bandyopadhyay

2
RemoveTextAddText方法应该是public void,缺少无效。正如@BibaswannBandyopadhyay所说,RemoveText方法可能是这样的:if (myTxtbx.Text == "Enter text here...") {myTxtbx.Text = "";}
KaKa

91

您可以使用它,它对我有用,并且是非常简单的解决方案。

    <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"/>

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎


1
@MacGile,您好,我修改了您的出色解决方案,因为我需要在原始text属性和textSource.Text属性之间进行双向绑定。
的Gabor Plesz

1
@Rob将其放在资源字典中。Window.Resources等
布莱恩

6
对于焦点问题,请添加以下内容: <ControlTemplate.Triggers> <Trigger Property="IsFocused" Value="True"> <Setter Property="FocusManager.FocusedElement" TargetName="textSource" Value="{Binding RelativeSource={RelativeSource Self}}" /> </Trigger> </ControlTemplate.Triggers>
Cihan Yakar 2015年

1
我钉在TextWrapping="wrap"上无论是在样式文本框的标签,如果你想要做一个多行文本框与占位符文本像我一样。
jpcguy89

1
@Sachin我已经修复了我的MaxLenght属性。问题是一个文本框被2个文本框替换。一种用于输入,另一种用于占位符。要修复损坏的属性,您只需将它们添加到第一个文本框中,如下所示:<TextBox Text="{Binding Path=Text, RelativeSource=RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="textSource" Background="Transparent" Panel.ZIndex="2" MaxLength="{TemplateBinding MaxLength}" />。根据您的情况,您可能需要添加AcceptsReturn="{TemplateBinding AcceptsReturn}"
ColmanJ,2016年

47

代替处理焦点进入和焦点离开事件来设置和删除占位符文本,可以使用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);

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

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

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


10
注意:这不适用于WPF。参见:stackoverflow.com/questions/5054872/…–
ArtOfCode

最好的答案在这里,但是请注意 Form_Load还为时过早,我不得不等到Form_Shown才起作用。
杰伊·克罗汉

我唯一讨厌的是,一旦控件获得焦点,文本就会消失,这意味着如果您没有听懂它说的话(这很重要),则必须单击该文本才能再次看到占位符文本。我添加了另一个答案,以添加一个占位符,该占位符仅在用户开始键入后才消失。
加布里埃尔·卢西

19

将此类添加到您的项目并构建您的解决方案。单击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();
    }
}

11
当某些其他控件对Text属性的值起作用时(例如,用于过滤列表的文本框),将使用占位符进行过滤。占位符值仅应用于显示,因此Text暂时替换属性不是一个好主意。
罗兰·伊利格

1
干净的解决方案,我喜欢它。为了使它起作用,我将在类的顶部添加这些用法:using System; using System.Drawing; using System.Windows.Forms;谢谢!
Eldoïr

18

这不是我的代码,但是我经常使用它,并且效果很好。仅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>

1
就像一个咒语一样,如果您用DataTrigger以下替换替换向IsFocused添加触发器,按MultiDataTrigger我的拙见,它的效果更好:<MultiDataTrigger><MultiDataTrigger.Conditions><Condition Binding="{Binding IsFocused, ElementName=Textbox}" Value="false" /><Condition Binding="{Binding Text, ElementName=Textbox}" Value="" /></MultiDataTrigger.Conditions><MultiDataTrigger.Setters> <Setter Property="Visibility" Value="Visible"/></MultiDataTrigger.Setters></MultiDataTrigger>
Akku

9

救援的附加属性:

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

        SetPlaceholder(dependencyObject, args.NewValue as string);

        if (!tb.IsFocused)
            ShowPlaceholder(tb);
    }

    private static void OnLostFocus(object sender, RoutedEventArgs routedEventArgs)
    {
        ShowPlaceholder(sender as TextBox);
    }

    private static void OnGotFocus(object sender, RoutedEventArgs routedEventArgs)
    {
        HidePlaceholder(sender as TextBox);
    }

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

    private static void ShowPlaceholder(TextBox textBox)
    {
        if (string.IsNullOrWhiteSpace(textBox.Text))
        {
            textBox.Text = GetPlaceholder(textBox);
        }
    }

    private static void HidePlaceholder(TextBox textBox)
    {
        string placeholderText = GetPlaceholder(textBox);

        if (textBox.Text == placeholderText)
            textBox.Text = string.Empty;
    }
}

用法:

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

感谢您提供这个不错的解决方案。但是,使用您的解决方案会导致:a)黑色的占位符文本,而不是浅灰色的占位符文本; b)在应用程序启动时(但在聚焦然后在其他位置设置聚焦之后)不显示任何占位符文本。您介意在这方面改善您的答案吗?
Yoda

1
@Yoda如果我管理,不要忘记它,直到我回家,我会考虑改进它,是的-为什么不
后海湾干线

1
空白的占位符,直到聚焦/未聚焦。
谢尔盖

1
@Yoda嗨,我不介意它是否经过仔细处理并且没有破坏任何内容。
谢尔盖

1
@Yoda,对不起,我已经有一段时间没有使用WPF了,目前我还没有安装它。您可以添加另一个名为依赖属性PlaceholderColortypeof(Brush)。然后textBox.ForegroundShowPlaceholder方法中更改属性,然后将其还原回HidePlaceholder方法中。
谢尔盖

5

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

因此,这是WinForms的另一种解决方案。它覆盖了Label控件的顶部,仅当用户开始键入时才消失。

这当然不是防弹的。它可以接受任何东西Control,但是我只测试了一个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;
}

4

根据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;
    }
}


3

这意味着您将拥有一个按钮,该按钮使您可以执行某项操作,例如登录等。在执行操作之前,请检查文本框是否已填写。如果未填写,它将替换文本

 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#以获得更好的解决方案。


2
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"/>

请说明您的答案,而不仅仅是将一堆代码转储到您的答案中。
基金莫妮卡的诉讼

1

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

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

1

在这里,我提供了受@Kemal Karadag启发的解决方案。

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

虽然我希望占位符是Google Chrome中标准HTML占位符的精确副本。

当框处于聚焦状态时,与其隐藏/显示占位符,不如说是,

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

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

由于它是从标准TextBox继承的,因此可以在工具箱中找到它!

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

0

尝试以下代码:

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


0

您也可以在单击鼠标时执行此操作,假设您的占位符文本为“ User_Name”

 private void textBox1_MouseClick(object sender, MouseEventArgs e)
 {
     if(textBox1.Text == "User_Name")
          textBox1.Text = "";
 }

0
    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;
            }
        };
    }

5
问题已经解决,该答案的附加值是什么?没有解释,请全部解释。
Jannik

0

我没有使用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

结果: 在此处输入图片说明


0

您也可以这样尝试。

调用函数

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

        };
}

0

有更好的解决方案,但是最简单的解决方案在这里:将文本框文本设置为所需的字符串,然后创建一个删除文本的函数,使该函数在文本框上触发Focus Enter事件


0

我写了一个可重用的自定义控件,也许它可以帮助需要在他的项目中实现多个占位符文本框的人。
这是带有实例实现示例的自定义类,您可以通过使用VS将代码粘贴到新的winforms项目上来轻松进行测试:

namespace reusebleplaceholdertextbox
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // implementation
            CustomPlaceHolderTextbox myCustomTxt = new CustomPlaceHolderTextbox(
                "Please Write Text Here...", Color.Gray, new Font("ARIAL", 11, FontStyle.Italic)
                , Color.Black, new Font("ARIAL", 11, FontStyle.Regular)
                );

            myCustomTxt.Multiline = true;
            myCustomTxt.Size = new Size(200, 50);
            myCustomTxt.Location = new Point(10, 10);
            this.Controls.Add(myCustomTxt);
        }
    }

    class CustomPlaceHolderTextbox : System.Windows.Forms.TextBox
    {
        public string PlaceholderText { get; private set; }
        public Color PlaceholderForeColor { get; private set; }
        public Font PlaceholderFont { get; private set; }

        public Color TextForeColor { get; private set; }
        public Font TextFont { get; private set; }

        public CustomPlaceHolderTextbox(string placeholdertext, Color placeholderforecolor,
            Font placeholderfont, Color textforecolor, Font textfont)
        {
            this.PlaceholderText = placeholdertext;
            this.PlaceholderFont = placeholderfont;
            this.PlaceholderForeColor = placeholderforecolor;
            this.PlaceholderFont = placeholderfont;
            this.TextForeColor = textforecolor;
            this.TextFont = textfont;
            if (!string.IsNullOrEmpty(this.PlaceholderText))
            {
                SetPlaceHolder(true);
                this.Update();
            }
        }

        private void SetPlaceHolder(bool addEvents)
        {
            if (addEvents)
            {  
                this.LostFocus += txt_lostfocus;
                this.Click += txt_click;
            }

            this.Text = PlaceholderText;
            this.ForeColor = PlaceholderForeColor;
            this.Font = PlaceholderFont;
        }

        private void txt_click(object sender, EventArgs e)
        {
            // IsNotFirstClickOnThis:
            // if there is no other control in the form
            // we will have a problem after the first load
            // because we dont other focusable control to move the focus to
            // and we dont want to remove the place holder
            // only on first time the place holder will be removed by click event
            RemovePlaceHolder();
            this.GotFocus += txt_focus;
            // no need for this event listener now
            this.Click -= txt_click;
        }

        private void RemovePlaceHolder()
        {
            this.Text = "";
            this.ForeColor = TextForeColor;
            this.Font = TextFont;
        }
        private void txt_lostfocus(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.Text))
            {
                // set placeholder again
                SetPlaceHolder(false);
            }
        }

        private void txt_focus(object sender, EventArgs e)
        {
            if (this.Text == PlaceholderText)
            {
                // IsNotFirstClickOnThis:
                // if there is no other control in the form
                // we will have a problem after the first load
                // because we dont other focusable control to move the focus to
                // and we dont want to remove the place holder
                RemovePlaceHolder();
            }
        }
    }
}

-1

非常有效的解决这里的WindowsForms TextBox控件。(不确定XAML)。

这也将在多重模式下工作。

可能会将其扩展为其他控件,例如ComboBox控件(未选中)


-1

奇迹般有效。

public class WTextBox : TextBox
{
    private string _placeholder;


    [Category("Appearance")]
    public string Placeholder
    {
        get { return _placeholder; }
        set
        {
            _placeholder = value ?? string.Empty;
            Invalidate();
        }
    }

    public WTextBox()
    {
        _placeholder = string.Empty;
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        if (m.Msg != 0xF || Focused || !string.IsNullOrEmpty(Text) || string.IsNullOrWhiteSpace(_placeholder))
        {
            return;
        }

        using (var g = CreateGraphics())
        {
            TextRenderer.DrawText(g, _placeholder, Font, ClientRectangle, SystemColors.GrayText, BackColor, TextFormatFlags.Left);
        }
    }
}

请添加必要的用法
Akku
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.