Aggiunta di testo segnaposto alla casella di testo


147

Sto cercando un modo per aggiungere testo segnaposto a una casella di testo come puoi con una casella di testo in HTML5.

Vale a dire se la casella di testo non ha testo, quindi aggiunge il testo Enter some text here, quando l'utente fa clic su di esso il testo segnaposto scompare e consente all'utente di inserire il proprio testo e se la casella di testo perde lo stato attivo e non c'è ancora testo, il segnaposto è aggiunto di nuovo alla casella di testo.


4
Non utilizzare la proprietà Text per il testo segnaposto. Interferirà con l'associazione. Usa AdornerDecorator ( msdn.microsoft.com/en-us/library/... )
Pavel Voronin


5
Solo un FYI - Watermark aka suggerimento testo aka segnaposto testo aka stecca banner . Tutti questi termini hanno anche intenzione.
RBT,

Risposte:


91

Non sarebbe solo qualcosa del genere:

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

Questo è solo pseudocodice ma il concetto è lì.


Grazie, mi aspettavo che ci fosse una sorta di XAML che può essere usato per creare il segnaposto. Grazie per l'aiuto
Boardy

1
Speravo di trovare una soluzione che mantenga il testo segnaposto nella casella di testo fino a quando l'utente non immette il testo. Sembra che funzionerebbe meglio.
Utenti DROP TABLE il

6
Funzionerà MA se il valore della casella di testo è associato all'origine, allora probabilmente hai un problema.
Pavel Voronin,

1
Questa è una buona soluzione semplice, l'unica cosa è che anche dopo aver inserito il testo, se l'utente fa di nuovo clic sulla casella di testo (ad esempio per aggiungere più testo o eliminare alcuni caratteri) l'intera casella di testo perderà il valore inserito
Bibaswann Bandyopadhyay

2
RemoveTexte il AddTextmetodo dovrebbe essere public void, vuoto mancante . E come ha detto @BibaswannBandyopadhyay, il RemoveTextmetodo potrebbe essere questo:if (myTxtbx.Text == "Enter text here...") {myTxtbx.Text = "";}
KaKa

91

Puoi usarlo, funziona per me ed è una soluzione estremamente semplice.

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

Uso:

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

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


1
Ciao @MacGile, ho modificato la tua ottima soluzione, perché ho bisogno del legame bidirezionale tra la proprietà text originale e textSource.Text.
Gábor Plesz,

1
@Rob lo inserisce in un dizionario delle risorse. Window.Resources, ecc.
Brian

6
Per problemi di messa a fuoco aggiungere questo: <ControlTemplate.Triggers> <Trigger Property="IsFocused" Value="True"> <Setter Property="FocusManager.FocusedElement" TargetName="textSource" Value="{Binding RelativeSource={RelativeSource Self}}" /> </Trigger> </ControlTemplate.Triggers>
Cihan Yakar

1
Mi attaccherei a TextWrapping="wrap"entrambi i tag TextBox nello stile, nel caso in cui tu voglia fare una TextBox multilinea con testo segnaposto come ho fatto io.
jpcguy89,

1
@Sachin Ho corretto la mia proprietà MaxLenght. Il problema è che una casella di testo viene sostituita con 2 caselle di testo. Uno per l'input e uno per il segnaposto. Per risolvere rotto proprietà è sufficiente aggiungerli al primo testo in questo modo: <TextBox Text="{Binding Path=Text, RelativeSource=RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="textSource" Background="Transparent" Panel.ZIndex="2" MaxLength="{TemplateBinding MaxLength}" />. Nel tuo caso probabilmente dovrai aggiungereAcceptsReturn="{TemplateBinding AcceptsReturn}"
ColmanJ,

47

Invece di gestire gli eventi focus enter e focus exit per impostare e rimuovere il testo segnaposto è possibile utilizzare la funzione Windows SendMessage per inviare EM_SETCUEBANNERmessaggi alla nostra casella di testo per fare il lavoro per noi.

Questo può essere fatto con due semplici passaggi. Per prima cosa dobbiamo esporre la SendMessagefunzione di Windows .

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

Quindi chiama semplicemente il metodo con l'handle della nostra casella di testo, il valore di EM_SETCUEBANNER e il testo che vogliamo impostare.

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

Riferimento: imposta il testo segnaposto per la casella di testo (cue text)


10
Nota: questo non funziona per WPF . Vedi: stackoverflow.com/questions/5054872/...
artofcode

La migliore risposta qui, ma nota che Form_Load è troppo presto, ho dovuto aspettare fino a Form_Shown prima che funzionasse.
Jay Croghan,

L'unica cosa che odio di questo è che il testo scompare non appena il controllo viene messo a fuoco, il che significa che se non hai capito cosa diceva (ed è importante), devi fare clic su di esso per vedere di nuovo il testo segnaposto . Ho aggiunto un'altra risposta per aggiungere un segnaposto che scompare solo dopo che l'utente inizia a digitare.
Gabriel Luci,

19

Aggiungi a questa classe il tuo progetto e crea la tua soluzione. Fare clic su Toolbox su Visual Studio vedrai un nuovo componente casella di testo chiamato PlaceholderTextBox. Eliminare la casella di testo corrente nel design del modulo e sostituirla con PlaceHolderTextBox.

inserisci qui la descrizione dell'immagine

PlaceHolderTextBox ha una proprietà PlaceHolderText. Imposta il testo che desideri e buona giornata :)

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
Quando un altro controllo agisce sul valore della Textproprietà (ad esempio una casella di testo utilizzata per filtrare un elenco), il segnaposto verrà utilizzato per il filtro. Il valore segnaposto deve essere utilizzato solo per la visualizzazione, pertanto non è consigliabile sostituire Texttemporaneamente la proprietà.
Roland Illig,

1
Soluzione ordinata, mi piace. Vorrei aggiungere questi usi in cima alla classe, per farlo funzionare: using System; using System.Drawing; using System.Windows.Forms;grazie per questo!
Eldoïr,

18

Questo non è il mio codice, ma lo uso molto e funziona perfettamente ... SOLO 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
Funziona come un incantesimo e se aggiungi un trigger a IsFocused sostituendolo DataTriggercon il seguente MultiDataTrigger, funziona ancora meglio secondo il mio modesto parere:<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

Proprietà associate al salvataggio:

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

Uso:

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

Grazie per aver fornito questa bella soluzione. Tuttavia, usando la tua soluzione, si ottiene a) un testo segnaposto nero anziché grigio chiaro eb) non mostra alcun testo segnaposto all'avvio dell'applicazione (ma dopo la messa a fuoco e l'impostazione della messa a fuoco altrove). Ti dispiacerebbe migliorare la tua risposta al riguardo?
Yoda,

1
@Yoda Se riesco a non dimenticarlo fino a quando non torno a casa, cercherò di migliorarlo, sì - perché no
Dbl

1
Segnaposto vuoto fino a quando la messa a fuoco / sfocatura è fissa
Sergey

1
@Yoda Ciao, non mi importa se è fatto con cura e non rompe nulla.
Sergey

1
@Yoda, scusa, non lavoro con WPF da un po ', non l'ho nemmeno installato al momento. È possibile aggiungere un'altra proprietà di dipendenza denominata PlaceholderColorcon typeof(Brush). Quindi modificare la textBox.Foregroundproprietà nel ShowPlaceholdermetodo e ripristinarla nel HidePlaceholdermetodo.
Sergey,

5

Durante l'utilizzo di EM_SETCUEBANNER messaggio è probabilmente più semplice, una cosa che non mi piace è che il testo segnaposto scompare quando il controllo viene attivato. Questa è una mia piccola pipì quando compilo i moduli. Devo selezionarlo per ricordare a cosa serve il campo.

Quindi ecco un'altra soluzione per WinForms. Si sovrappone Labela sopra il controllo, che scompare solo quando l'utente inizia a digitare.

Non è certo a prova di proiettile. Accetta qualsiasi Control, ma ho provato solo con a TextBox. Potrebbe essere necessario apportare modifiche per funzionare con alcuni controlli. Il metodo restituisce il Labelcontrollo nel caso in cui sia necessario modificarlo un po 'in un caso specifico, ma potrebbe non essere mai necessario.

Usalo in questo modo:

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

Ecco il metodo:

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

Basato sulla risposta di ExceptionLimeCat, un miglioramento:

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

Ciò significherebbe che hai un pulsante che ti consente di fare un'azione, come il login o qualcosa del genere. Prima di eseguire l'azione, controlla se la casella di testo è compilata. In caso contrario, sostituirà il testo

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

È un po 'sdolcinato, ma controllare il testo per il valore che stai dando è il meglio che posso fare atm, non così bravo in c # per ottenere una soluzione migliore.


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

Spiega la tua risposta anziché semplicemente scaricare un sacco di codice nella tua risposta.
Fondo Monica's Lawsuit

1

Ho trovato un metodo che ha funzionato per me, ma solo perché ero disposto a usare il nome della casella di testo come segnaposto. Vedi sotto.

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

Qui vengo con questa soluzione ispirata a @Kemal Karadag.

Ho notato che ogni soluzione pubblicata qui si basa sull'attenzione,

Mentre volevo che il mio segnaposto fosse il clone esatto di un segnaposto HTML standard in Google Chrome.

Invece di nascondere / mostrare il segnaposto quando la casella è focalizzata,

Nascondo / mostro il segnaposto in base alla lunghezza del testo della casella:

Se la casella è vuota, viene visualizzato il segnaposto e se si digita nella casella, il segnaposto scompare.

Essendo ereditato da una TextBox standard, puoi trovarlo nella tua Toolbox!

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

Prova il seguente codice:

<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

puoi anche farlo quando fai clic con il mouse, supponiamo che il tuo segnaposto sia "Nome_utente"

 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
La domanda è già risolta, cosa sta usando il valore aggiunto di questa risposta? Non c'è spiegazione aggiungere tutto, prova a spiegarlo.
Jannik,

0

Invece di utilizzare la proprietà .Text di un oggetto TextBox, ho sovrapposto un oggetto TextBlock con il segnaposto. Non ho potuto usare la proprietà .Text perché è stato associato a un evento.

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

Risultato: inserisci qui la descrizione dell'immagine


0

Puoi anche provare in questo modo ..

chiama la funzione

TextboxPlaceHolder(this.textBox1, "YourPlaceHolder");

scrivi questa funzione

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

ci sono soluzioni MIGLIORI, ma la soluzione più semplice è qui: imposta il testo della casella di testo sulla stringa desiderata, quindi crea una funzione che elimina il testo, attiva quella funzione sulla casella di testo Fuoco Inserisci evento


0

Ho scritto un controllo personalizzato riutilizzabile, forse può aiutare qualcuno che deve implementare più caselle di testo segnaposto nel suo progetto.
ecco la classe personalizzata con esempio di implementazione di un'istanza, puoi testare facilmente incollando questo codice su un nuovo progetto winforms usando 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

Soluzione molto efficace qui per il controllo TextBox di WindowsForms. (non sono sicuro di XAML).

Funzionerà anche in modalità multilinea.

Probabilmente può essere esteso per altri controlli, come il controllo ComboBox (non selezionato)


-1

Funziona come un fascino.

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

Si prega di aggiungere gli usi necessari
Akku
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.