html5のテキストボックスでできるように、プレースホルダーテキストをテキストボックスに追加する方法を探しています。
つまり、テキストボックスにテキストがない場合はテキストが追加さEnter some text here
れ、ユーザーがクリックするとプレースホルダーテキストが消えてユーザーが独自のテキストを入力できるようになります。テキストボックスにフォーカスがなくてもテキストがない場合、プレースホルダーは次のようになります。テキストボックスに追加し直しました。
html5のテキストボックスでできるように、プレースホルダーテキストをテキストボックスに追加する方法を探しています。
つまり、テキストボックスにテキストがない場合はテキストが追加さEnter some text here
れ、ユーザーがクリックするとプレースホルダーテキストが消えてユーザーが独自のテキストを入力できるようになります。テキストボックスにフォーカスがなくてもテキストがない場合、プレースホルダーは次のようになります。テキストボックスに追加し直しました。
それはこのようなものではないでしょうか:
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...";
}
それは単なる擬似コードですが、概念はそこにあります。
あなたはこれを使うことができます、それは私のために働いていて、そして非常に単純な解決策です。
<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>
プレースホルダーテキストを設定および削除するためにフォーカス入力イベントとフォーカス終了イベントを処理する代わりに、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");
このクラスをプロジェクトに追加し、ソリューションを構築します。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();
}
}
これは私のコードではありませんが、私はそれを頻繁に使用し、完璧に機能します...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>
レスキューに添付されたプロパティ:
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>
メッセージの使用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;
}
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;
}
}
デフォルトTemplate
を取得し、をオーバーレイして変更しTextBlock
、を使用しStyle
て、適切な状態で非表示および表示するトリガーを追加できます。
これは、ログインなどのアクションを実行できるボタンがあることを意味します。アクションを実行する前に、テキストボックスが入力されているかどうかを確認します。入力されていない場合は、テキストが置き換えられます
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#が得意ではありません。
これが古いスレッドであることは知っていますが、.NETCoreと.NET5.0はTextBox.PlaceholderText
プロパティを実装しています。
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"/>
ここに、@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();
}
}
}
これは、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
私は自分に合った方法を思いつきましたが、それはテキストボックス名をプレースホルダーとして使用することをいとわなかったからです。下記参照。
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;
}
}
次のコードを試してください。
<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>
マウスをクリックしたときに、プレースホルダーテキストが「User_Name」であると仮定することもできます。
private void textBox1_MouseClick(object sender, MouseEventArgs e)
{
if(textBox1.Text == "User_Name")
textBox1.Text = "";
}
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;
}
};
}
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
この方法で試すこともできます。
関数を呼び出す
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;
}
};
}
より良い解決策がありますが、最も簡単な解決策はここにあります。テキストボックスのテキストを目的の文字列に設定してから、テキストを削除する関数を作成し、その関数をテキストボックスのフォーカス入力イベントで起動します。
再利用可能なカスタムコントロールを作成しました。プロジェクトに複数のプレースホルダーテキストボックスを実装する必要がある人に役立つかもしれません。
これは、インスタンスの実装例を含むカスタムクラスです。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();
}
}
}
}
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;
}
}
}
txtUsuario.Attributes.Add( "placeholder"、 "Texto");
ここでは、WindowsFormsTextBoxコントロールの非常に効果的なソリューションです。(XAMLについてはわかりません)。
これはマルチリンモードでも機能します。
おそらく、ComboBoxコントロール(チェックされていない)などの他のコントロール用に拡張される可能性があります
チャームのように機能します。
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);
}
}
}