169

html5のテキストボックスでできるように、プレースホルダーテキストをテキストボックスに追加する方法を探しています。

つまり、テキストボックスにテキストがない場合はテキストが追加さEnter some text hereれ、ユーザーがクリックするとプレースホルダーテキストが消えてユーザーが独自のテキストを入力できるようになります。テキストボックスにフォーカスがなくてもテキストがない場合、プレースホルダーは次のようになります。テキストボックスに追加し直しました。

4

26 に答える 26

105

それはこのようなものではないでしょうか:

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

それは単なる擬似コードですが、概念はそこにあります。

于 2012-08-08T21:34:03.987 に答える
103

あなたはこれを使うことができます、それは私のために働いていて、そして非常に単純な解決策です。

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

</ p>

于 2014-01-29T18:17:17.323 に答える
54

プレースホルダーテキストを設定および削除するためにフォーカス入力イベントとフォーカス終了イベントを処理する代わりに、WindowsのSendMessage関数を使用し EM_SETCUEBANNERて、テキストボックスにメッセージを送信して作業を行うことができます。

これは、2つの簡単な手順で実行できます。まず、WindowsSendMessage関数を公開する必要があります。

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

参照:テキストボックスのプレースホルダーテキストを設定する(キューテキスト)

于 2014-03-14T12:49:53.770 に答える
26

このクラスをプロジェクトに追加し、ソリューションを構築します。Visual Studioのツールボックスをクリックすると、PlaceholderTextBoxという名前の新しいテキストボックスコンポーネントが表示されます。フォームdesigneの現在のテキストボックスを削除し、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();
    }
}
于 2016-05-18T07:11:52.867 に答える
22

これは私のコードではありませんが、私はそれを頻繁に使用し、完璧に機能します...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>
于 2015-10-29T09:38:16.387 に答える
10

レスキューに添付されたプロパティ:

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>
于 2016-04-28T09:00:55.240 に答える
7

メッセージの使用EM_SETCUEBANNERはおそらく最も簡単ですが、私が気に入らないことの1つは、コントロールがフォーカスを取得するとプレースホルダーのテキストが消えることです。私がフォームに記入しているとき、それは私のペットのぞき見です。フィールドが何のためにあるかを思い出すためにそれをクリックする必要があります。

したがって、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;
}
于 2016-12-12T17:05:49.513 に答える
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;
    }
}
于 2016-06-11T10:27:50.227 に答える
3

デフォルトTemplateを取得し、をオーバーレイして変更しTextBlock、を使用しStyleて、適切な状態で非表示および表示するトリガーを追加できます。

于 2012-08-08T22:02:19.647 に答える
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#が得意ではありません。

于 2015-02-20T08:07:27.347 に答える
3

これが古いスレッドであることは知っていますが、.NETCoreと.NET5.0はTextBox.PlaceholderTextプロパティを実装しています。

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

于 2021-06-16T04:15:17.850 に答える
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"/>
于 2017-01-07T09:42:42.030 に答える
2

ここに、@KemalKaradagに触発されたこのソリューションが付属しています。

ここに投稿されたすべてのソリューションがフォーカスに依存していることに気づきました。

プレースホルダーをGoogleChromeの標準の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();
        }
    }
}
于 2017-11-10T11:22:45.510 に答える
2

これは、texboxの拡張メソッドです。プログラムでプレースホルダーテキストを追加するだけです。

myTextBox.AddPlaceholderText("Hello World!");

拡張方法:

public static void AddPlaceholderText(this TextBox textBox, string placeholderText)
        {
            if (string.IsNullOrWhiteSpace(textBox.Text))
                textBox.Text = placeholderText;
            textBox.SetResourceReference(Control.ForegroundProperty,
                textBox.Text != placeholderText
                    ? "SystemControlForegroundBaseHighBrush"
                    : "SystemControlForegroundBaseMediumBrush");
            var ignoreSelectionChanged = false;
            textBox.SelectionChanged += (sender, args) =>
            {
                if (ignoreSelectionChanged) { ignoreSelectionChanged = false; return; }
                if (textBox.Text != placeholderText) return;
                ignoreSelectionChanged = true;
                textBox.Select(0, 0);
            };
            var lastText = textBox.Text;
            var ignoreTextChanged = false;
            textBox.TextChanged += (sender, args) =>
            {
                if (ignoreTextChanged) { ignoreTextChanged = false; return; }
                if (string.IsNullOrWhiteSpace(textBox.Text))
                {
                    ignoreTextChanged = true;
                    textBox.Text = placeholderText;
                    textBox.Select(0, 0);
                }
                else if (lastText == placeholderText)
                {
                    ignoreTextChanged = true;
                    textBox.Text = textBox.Text.Substring(0, 1);
                    textBox.Select(1, 0);
                }

                textBox.SetResourceReference(Control.ForegroundProperty,
                    textBox.Text != placeholderText
                        ? "SystemControlForegroundBaseHighBrush"
                        : "SystemControlForegroundBaseMediumBrush");
                lastText = textBox.Text;
            };
        }

ハッピーコーディング、BierDav

于 2020-09-18T20:07:41.677 に答える
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;
        }
    }
于 2014-02-14T17:55:50.500 に答える
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>
于 2014-11-18T15:20:04.807 に答える
0

マウスをクリックしたときに、プレースホルダーテキストが「User_Name」であると仮定することもできます。

 private void textBox1_MouseClick(object sender, MouseEventArgs e)
 {
     if(textBox1.Text == "User_Name")
          textBox1.Text = "";
 }
于 2015-01-31T05:49:07.013 に答える
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;
            }
        };
    }
于 2016-01-15T06:02:50.703 に答える
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

結果: ここに画像の説明を入力してください

于 2016-08-18T12:54:12.720 に答える
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;
            }

        };
}
于 2017-07-31T04:54:31.503 に答える
0

より良い解決策がありますが、最も簡単な解決策はここにあります。テキストボックスのテキストを目的の文字列に設定してから、テキストを削除する関数を作成し、その関数をテキストボックスのフォーカス入力イベントで起動します。

于 2018-07-23T23:24:08.727 に答える
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();
            }
        }
    }
}
于 2018-10-11T13:42:55.497 に答える
0

PlcaeHoldTextとPlaceHoldBackroundを使用してTextBoxを拡張してみましょう。プロジェクトからいくつかのコードを削除しました。

グリッドまたはキャンバスに別れを告げる!

<TextBox x:Class="VcpkgGui.View.PlaceHoldedTextBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:VcpkgGui.View"
             mc:Ignorable="d"
             Name="placeHoldTextBox"
             TextAlignment="Left"
         >
    <TextBox.Resources>
        <local:FrameworkWidthConverter x:Key="getElemWidth"/>
        <local:FrameworkHeightConverter x:Key="getElemHeight"/>
        <VisualBrush x:Key="PlaceHoldTextBrush" TileMode="None" Stretch="None" AlignmentX="Left" AlignmentY="Center" Opacity="1">
            <VisualBrush.Visual>
                <Border Background="{Binding ElementName=placeHoldTextBox, Path=PlaceHoldBackground}"
                        BorderThickness="0"
                        Margin="0,0,0,0"
                        Width="{Binding Mode=OneWay, ElementName=placeHoldTextBox, Converter={StaticResource getElemWidth}}"
                        Height="{Binding Mode=OneWay, ElementName=placeHoldTextBox, Converter={StaticResource getElemHeight}}"
                        >
                    <Label Content="{Binding ElementName=placeHoldTextBox, Path=PlaceHoldText}"
                           Background="Transparent"
                           Foreground="#88000000"
                           HorizontalAlignment="Stretch"
                           VerticalAlignment="Stretch"
                           HorizontalContentAlignment="Left"
                           VerticalContentAlignment="Center"
                           ClipToBounds="True"
                           Padding="0,0,0,0"
                           FontSize="14"
                           FontStyle="Normal"
                           Opacity="1"/>
                </Border>
            </VisualBrush.Visual>
        </VisualBrush>
    </TextBox.Resources>
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <Trigger Property="Text" Value="{x:Null}">
                    <Setter Property="Background"  Value="{StaticResource PlaceHoldTextBrush}"/>
                </Trigger>
                <Trigger Property="Text" Value="">
                    <Setter Property="Background"  Value="{StaticResource PlaceHoldTextBrush}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace VcpkgGui.View
{
    /// <summary>
    /// PlaceHoldedTextBox.xaml 的交互逻辑
    /// </summary>
    public partial class PlaceHoldedTextBox : TextBox
    {

        public string PlaceHoldText
        {
            get { return (string)GetValue(PlaceHoldTextProperty); }
            set { SetValue(PlaceHoldTextProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PlaceHolderText.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PlaceHoldTextProperty =
            DependencyProperty.Register("PlaceHoldText", typeof(string), typeof(PlaceHoldedTextBox), new PropertyMetadata(string.Empty));



        public Brush PlaceHoldBackground
        {
            get { return (Brush)GetValue(PlaceHoldBackgroundProperty); }
            set { SetValue(PlaceHoldBackgroundProperty, value); }
        }

        public static readonly DependencyProperty PlaceHoldBackgroundProperty =
            DependencyProperty.Register(nameof(PlaceHoldBackground), typeof(Brush), typeof(PlaceHoldedTextBox), new PropertyMetadata(Brushes.White));

        public PlaceHoldedTextBox() :base()
        {
            InitializeComponent();
        }
    }

    [ValueConversion(typeof(FrameworkElement), typeof(double))]
    internal class FrameworkWidthConverter : System.Windows.Data.IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if(value is FrameworkElement elem)
                return double.IsNaN(elem.Width) ? elem.ActualWidth : elem.Width;
            else
                return DependencyProperty.UnsetValue;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return DependencyProperty.UnsetValue;
        }
    }

    [ValueConversion(typeof(FrameworkElement), typeof(double))]
    internal class FrameworkHeightConverter : System.Windows.Data.IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is FrameworkElement elem)
                return double.IsNaN(elem.Height) ? elem.ActualHeight : elem.Height;
            else
                return DependencyProperty.UnsetValue;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return DependencyProperty.UnsetValue;
        }
    }

}
于 2020-10-24T07:35:12.960 に答える
-1

txtUsuario.Attributes.Add( "placeholder"、 "Texto");

于 2015-08-28T14:04:45.283 に答える
-1

ここでは、WindowsFormsTextBoxコントロールの非常に効果的なソリューションです。(XAMLについてはわかりません)。

これはマルチリンモードでも機能します。

おそらく、ComboBoxコントロール(チェックされていない)などの他のコントロール用に拡張される可能性があります

于 2018-08-30T11:41:00.923 に答える
-2

チャームのように機能します。

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);
        }
    }
}
于 2019-07-31T14:19:43.860 に答える