Додавання тексту заповнювача до текстового поля


147

Я шукаю спосіб додати текст заповнювача до текстового поля, як ви можете, з текстовим полем у html5.

Тобто, якщо в текстовому полі немає тексту, він додає текст Enter some text here, коли користувач натискає на нього, текст із заповнювача зникає і дозволяє користувачеві вводити власний текст, а якщо текстове поле втрачає фокус і все ще немає тексту, то заповнювач є додано назад до текстового поля.


4
Не використовуйте властивість Text для тексту-заповнювача. Це буде заважати зв’язуванню. Використовуйте AdornerDecorator ( msdn.microsoft.com/en-us/library/… )
Павло Воронін

2
Подивіться на stackoverflow.com/questions/833943 / ...
SepehrM

5
Просто FYI - Watermark aka текст підказки aka текст заповнення aka aka cue банер . Усі ці терміни мають синонімічний намір.
RBT

Відповіді:


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
Це працюватиме АЛЕ якщо значення текстового поля буде пов'язане з джерелом, то, ймовірно, у вас є проблеми.
Павло Воронін

1
Це хороше просте рішення, єдине, що навіть після введення тексту, якщо користувач знову натисне на текстове поле (наприклад, щоб додати більше тексту або видалити деякі символи), вся текстова
скринька

2
RemoveTextі AddTextметод повинен бути 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, я змінив ваше чудове рішення, тому що мені потрібно двостороння прив'язка між оригінальною властивістю тексту та властивістю textSource.Text.
Габор Плеш

1
@Rob помістив його у словник ресурсів. Window.Ресурси тощо
Брайан

6
Для проблем фокусування додайте це: <ControlTemplate.Triggers> <Trigger Property="IsFocused" Value="True"> <Setter Property="FocusManager.FocusedElement" TargetName="textSource" Value="{Binding RelativeSource={RelativeSource Self}}" /> </Trigger> </ControlTemplate.Triggers>
Cihan Yakar

1
Я б торкнувся TextWrapping="wrap"обох тегів TextBox у стилі, якщо ви хочете зробити багаторядковий TextBox з текстом заповнювача, як я.
jpcguy89

1
@Sachin Я виправив майно MaxLenght. Проблема полягає в тому, що одне текстове поле замінено двома текстовими полями. Один для введення та один для заповнювача. Щоб виправити биті властивостей потрібно просто додати їх у першу текстове поле , як це: <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

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

Додайте до цього класу свій проект та будуйте своє рішення. Натисніть на Панель інструментів у візуальній студії, ви побачите новий компонент текстового поля під назвою 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властивість тимчасово не годиться .
Roland Illig

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
Діє як шарм, і якщо ви додасте тригер до IsFocused, замінивши DataTriggerнаступне 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>
Акку

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>

Дякуємо, що надали це приємне рішення. Однак, використовуючи ваше рішення, результат: а) чорний текст-заповнювач замість світло-сірого та b) не показує тексту заповнення при запуску програми (але після фокусування та встановлення фокусу в іншому місці). Чи проти зауваження в цьому відношенні?
Йода

1
@Yoda Якщо мені вдасться не забути це, поки я не повернуся додому, я розглядаю його вдосконалення, так - чому б ні
Dbl

1
Порожній заповнювач, доки фокусування / розфокусування не виправлено.
Сергій

1
@Yoda Привіт, я не заперечую, якщо це робиться обережно і нічого не порушує.
Сергій

1
@Yoda, вибачте, я не працюю з WPF деякий час, я навіть не встановив його на даний момент. Ви можете додати ще одну властивість залежностей з ім'ям PlaceholderColorз typeof(Brush). Потім змініть textBox.Foregroundвластивість у ShowPlaceholderметоді та відновіть його назад у HidePlaceholderметоді.
Сергій

5

Хоча використання EM_SETCUEBANNERповідомлення, мабуть, найпростіше, одне, що мені не подобається, це те, що текст заповнювача зникає, коли елемент управління фокусується. Це моя домашня тварина, коли я заповнюю форми. Мені потрібно клацнути його, щоб запам'ятати, для чого це поле.

Тож ось ще одне рішення для WinForms. Він накладається у Labelверхній частині елемента керування, який зникає лише тоді, коли користувач почне вводити текст.

Це, звичайно, не куленепробивна. Він приймає будь-які Control, але я протестував лише з a 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.

Я помітив, що кожне рішення, розміщене тут, покладається на фокус,

Хоча я хотів, щоб мій заповнювач міг бути точним клоном стандартного заповнювача HTML в Google Chrome.

Замість того, щоб приховувати / показувати заповнювач, коли поле фокусується,

Я ховаю / показую заповнювач місця залежно від довжини тексту поля:

Якщо поле порожнє, відображається заповнювач, а якщо ви вводите поле, заповнювач зникає.

Оскільки він успадкований від стандартного 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

ви також можете це зробити, коли клацніть мишкою, припустимо, що текст вашого заповнювача "Username"

 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

Замість використання властивості .Text TextBox я наклав 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

Я написав користувальницький контрольний засіб для багаторазового використання, можливо, це може допомогти комусь, кому потрібно реалізувати декілька текстових полів заповнювачів у своєму проекті.
ось спеціальний клас із прикладом реалізації екземпляра, який ви можете легко протестувати, вставивши цей код у новий проект winforms за допомогою VS:

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

Це також буде працювати в режимі Multliline.

Можливо, він може бути розширений для інших елементів керування, наприклад керування 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);
        }
    }
}

Будь ласка, додайте необхідні
Акку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.