Boa*_*rdy 129 c# wpf placeholder
我正在寻找一种方法来将占位符文本添加到文本框中,就像在html5中使用文本框一样.
即如果文本框没有文本,则添加文本Enter some text here,当用户点击它时,占位符文本消失并允许用户输入自己的文本,如果文本框失去焦点但仍然没有文本,则占位符为添加回文本框.
小智 84
你可以使用它,它对我有用,是一个非常简单的解决方案.
<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>
Run Code Online (Sandbox Code Playgroud)
用法:
<TextBox Style="{StaticResource placeHolder}" Tag="Name of customer" Width="150" Height="24"/>
Run Code Online (Sandbox Code Playgroud)
Exc*_*Cat 76
这不是这样的事情:
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...";
}
Run Code Online (Sandbox Code Playgroud)
多数民众赞成只是伪代码,但概念就在那里.
Abd*_*eer 44
除了处理焦点输入和焦点离开事件以设置和删除占位符文本之外,还可以使用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);
Run Code Online (Sandbox Code Playgroud)
然后只需使用我们的文本框的句柄,EM_SETCUEBANNER的值和我们想要设置的文本调用该方法.
SendMessage(textBox1.Handle, EM_SETCUEBANNER, 0, "Username");
SendMessage(textBox2.Handle, EM_SETCUEBANNER, 0, "Password");
Run Code Online (Sandbox Code Playgroud)
小智 17
将此类添加到您的项目中并构建解决方案.单击Visual Studio上的工具箱,您将看到一个名为PlaceholderTextBox的新文本框组件.删除表单设计上的当前文本框,并替换为PlaceHolderTextBox.
PlaceHolderTextBox有一个属性PlaceHolderText.设置你想要的任何文字,并有美好的一天:)
public class PlaceHolderTextBox : TextBox
{
bool isPlaceHolder = true;
string _placeHolderText;
public string PlaceHolderText
{
get { return _placeHolderText; }
set
{
_placeHolderText = value;
setPlaceholder();
}
}
public new string Text
{
get => isPlaceHolder ? string.Empty : base.Text;
set => base.Text = value;
}
//when the control loses focus, the placeholder is shown
private void setPlaceholder()
{
if (string.IsNullOrEmpty(base.Text))
{
base.Text = PlaceHolderText;
this.ForeColor = Color.Gray;
this.Font = new Font(this.Font, FontStyle.Italic);
isPlaceHolder = true;
}
}
//when the control is focused, the placeholder is removed
private void removePlaceHolder()
{
if (isPlaceHolder)
{
base.Text = "";
this.ForeColor = System.Drawing.SystemColors.WindowText;
this.Font = new Font(this.Font, FontStyle.Regular);
isPlaceHolder = false;
}
}
public PlaceHolderTextBox()
{
GotFocus += removePlaceHolder;
LostFocus += setPlaceholder;
}
private void setPlaceholder(object sender, EventArgs e)
{
setPlaceholder();
}
private void removePlaceHolder(object sender, EventArgs e)
{
removePlaceHolder();
}
}
Run Code Online (Sandbox Code Playgroud)
小智 14
这不是我的代码,但是我经常使用它并且它非常完美......仅限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>
Run Code Online (Sandbox Code Playgroud)
救援的附属物:
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;
}
}
private static void OnLostFocus(object sender, RoutedEventArgs routedEventArgs)
{
var tb = sender as TextBox;
if (string.IsNullOrEmpty(tb.Text) || string.IsNullOrWhiteSpace(tb.Text))
{
tb.Text = GetPlaceholder(tb);
}
}
private static void OnGotFocus(object sender, RoutedEventArgs routedEventArgs)
{
var tb = sender as TextBox;
var ph = GetPlaceholder(tb);
if (tb.Text == ph)
{
tb.Text = string.Empty;
}
}
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
<TextBox Text="hi" local:TextboxExtensions.Placeholder="Hello there"></TextBox>
Run Code Online (Sandbox Code Playgroud)
基于 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;
}
}
Run Code Online (Sandbox Code Playgroud)
虽然使用该EM_SETCUEBANNER消息可能是最简单的,但我不喜欢的一点是占位符文本在控件获得焦点时消失.当我填写表格时,这是我的一个宠儿.我必须点击它才能记住该字段的用途.
所以这是WinForms的另一个解决方案.它覆盖Label在控件的顶部,仅在用户开始键入时消失.
它当然不是防弹的.它接受任何Control,但我只测试了一个TextBox.可能需要修改才能使用某些控件.该方法返回Label控件,以防您需要在特定情况下稍微修改它,但可能永远不需要.
像这样使用它:
SetPlaceholder(txtSearch, "Type what you're searching for");
Run Code Online (Sandbox Code Playgroud)
这是方法:
/// <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;
}
Run Code Online (Sandbox Code Playgroud)
我知道这是一个旧线程,但 .NET Core 和 .NET 5.0 已经实现了该TextBox.PlaceholderText属性。
| 归档时间: |
|
| 查看次数: |
244872 次 |
| 最近记录: |