我怎么能把一些文本放入一个文本框,这将被自动删除时,用户键入的东西在它?
当前回答
您可以为输入的文本保留一个单独的值,并且可以在“GotFocus”和“LostFocus”事件中设置文本框的“text”字段。当您获得焦点时,如果没有值,则需要清除文本框。当你失去焦点时,你会想要设置从文本框中获取“文本”值,然后将文本框的“文本”值重置为占位符(如果它是空的)。
private String username = "";
private void usernameTextBox_GotFocus(object sender, RoutedEventArgs e) {
if (String.IsNullOrEmpty(username)) {
usernameTextBox.Text = "";
}
}
private void usernameTextBox_LostFocus(object sender, RoutedEventArgs e) {
username = usernameTextBox.Text;
if (String.IsNullOrEmpty(usernameTextBox.Text)) {
usernameTextBox.Text = "Username";
}
}
然后,您只需确保文本框的“Text”值初始化为占位符文本。
<TextBox x:Name="usernameTextBox" Text="Username" GotFocus="usernameTextBox_GotFocus" LostFocus="usernameTextBox_LostFocus" />
您可以进一步将其提取到扩展“TextBox”类的类中,然后在整个项目中重用它。
namespace UI {
public class PlaceholderTextBox : TextBox {
public String Value { get; set; }
public String PlaceholderText { get; set; }
public Brush PlaceholderBrush { get; set; }
private Brush ValuedBrush { get; set; }
public PlaceholderTextBox() : base() {}
protected override void OnInitialized(EventArgs e) {
base.OnInitialized(e);
ValuedBrush = this.Foreground;
if (String.IsNullOrEmpty(this.Text)) {
this.Text = PlaceholderText;
this.Foreground = PlaceholderBrush;
}
}
protected override void OnGotFocus(System.Windows.RoutedEventArgs e) {
this.Foreground = ValuedBrush;
if (String.IsNullOrEmpty(Value)) {
this.Text = "";
}
base.OnGotFocus(e);
}
protected override void OnLostFocus(System.Windows.RoutedEventArgs e) {
Value = this.Text;
if (String.IsNullOrEmpty(this.Text)) {
this.Text = PlaceholderText;
this.Foreground = PlaceholderBrush;
}
base.OnLostFocus(e);
}
}
}
然后这个可以直接添加到xaml中。
<Window x:Class="UI.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:UI"
Initialized="Window_Initialized">
<Grid>
<m:PlaceholderTextBox x:Name="usernameTextBox" PlaceholderText="Username" PlaceholderBrush="Gray" />
</Grid>
</Window>
其他回答
这个库有水印。
Nuget包
示例用法:
<TextBox adorners:Watermark.Text="Write something here"
adorners:Watermark.TextStyle="{StaticResource AdornerTextStyle}"
adorners:Watermark.VisibleWhen="EmptyAndNotKeyboardFocused"/>
您可以为输入的文本保留一个单独的值,并且可以在“GotFocus”和“LostFocus”事件中设置文本框的“text”字段。当您获得焦点时,如果没有值,则需要清除文本框。当你失去焦点时,你会想要设置从文本框中获取“文本”值,然后将文本框的“文本”值重置为占位符(如果它是空的)。
private String username = "";
private void usernameTextBox_GotFocus(object sender, RoutedEventArgs e) {
if (String.IsNullOrEmpty(username)) {
usernameTextBox.Text = "";
}
}
private void usernameTextBox_LostFocus(object sender, RoutedEventArgs e) {
username = usernameTextBox.Text;
if (String.IsNullOrEmpty(usernameTextBox.Text)) {
usernameTextBox.Text = "Username";
}
}
然后,您只需确保文本框的“Text”值初始化为占位符文本。
<TextBox x:Name="usernameTextBox" Text="Username" GotFocus="usernameTextBox_GotFocus" LostFocus="usernameTextBox_LostFocus" />
您可以进一步将其提取到扩展“TextBox”类的类中,然后在整个项目中重用它。
namespace UI {
public class PlaceholderTextBox : TextBox {
public String Value { get; set; }
public String PlaceholderText { get; set; }
public Brush PlaceholderBrush { get; set; }
private Brush ValuedBrush { get; set; }
public PlaceholderTextBox() : base() {}
protected override void OnInitialized(EventArgs e) {
base.OnInitialized(e);
ValuedBrush = this.Foreground;
if (String.IsNullOrEmpty(this.Text)) {
this.Text = PlaceholderText;
this.Foreground = PlaceholderBrush;
}
}
protected override void OnGotFocus(System.Windows.RoutedEventArgs e) {
this.Foreground = ValuedBrush;
if (String.IsNullOrEmpty(Value)) {
this.Text = "";
}
base.OnGotFocus(e);
}
protected override void OnLostFocus(System.Windows.RoutedEventArgs e) {
Value = this.Text;
if (String.IsNullOrEmpty(this.Text)) {
this.Text = PlaceholderText;
this.Foreground = PlaceholderBrush;
}
base.OnLostFocus(e);
}
}
}
然后这个可以直接添加到xaml中。
<Window x:Class="UI.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:UI"
Initialized="Window_Initialized">
<Grid>
<m:PlaceholderTextBox x:Name="usernameTextBox" PlaceholderText="Username" PlaceholderBrush="Gray" />
</Grid>
</Window>
好吧,这是我的:不一定是最好的,但因为它很简单,很容易编辑到你的口味。
<UserControl x:Class="WPFControls.ShadowedTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFControls"
Name="Root">
<UserControl.Resources>
<local:ShadowConverter x:Key="ShadowConvert"/>
</UserControl.Resources>
<Grid>
<TextBox Name="textBox"
Foreground="{Binding ElementName=Root, Path=Foreground}"
Text="{Binding ElementName=Root, Path=Text, UpdateSourceTrigger=PropertyChanged}"
TextChanged="textBox_TextChanged"
TextWrapping="Wrap"
VerticalContentAlignment="Center"/>
<TextBlock Name="WaterMarkLabel"
IsHitTestVisible="False"
Foreground="{Binding ElementName=Root,Path=Foreground}"
FontWeight="Thin"
Opacity=".345"
FontStyle="Italic"
Text="{Binding ElementName=Root, Path=Watermark}"
VerticalAlignment="Center"
TextWrapping="Wrap"
TextAlignment="Center">
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource ShadowConvert}">
<Binding ElementName="textBox" Path="Text"/>
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
</Grid>
这个转换器,就像它现在写的那样,它不一定是一个MultiConverter,但这样它可以很容易地扩展
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace WPFControls
{
class ShadowConverter:IMultiValueConverter
{
#region Implementation of IMultiValueConverter
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var text = (string) values[0];
return text == string.Empty
? Visibility.Visible
: Visibility.Collapsed;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new object[0];
}
#endregion
}
}
最后是背后的代码:
using System.Windows;
using System.Windows.Controls;
namespace WPFControls
{
/// <summary>
/// Interaction logic for ShadowedTextBox.xaml
/// </summary>
public partial class ShadowedTextBox : UserControl
{
public event TextChangedEventHandler TextChanged;
public ShadowedTextBox()
{
InitializeComponent();
}
public static readonly DependencyProperty WatermarkProperty =
DependencyProperty.Register("Watermark",
typeof (string),
typeof (ShadowedTextBox),
new UIPropertyMetadata(string.Empty));
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text",
typeof (string),
typeof (ShadowedTextBox),
new UIPropertyMetadata(string.Empty));
public static readonly DependencyProperty TextChangedProperty =
DependencyProperty.Register("TextChanged",
typeof (TextChangedEventHandler),
typeof (ShadowedTextBox),
new UIPropertyMetadata(null));
public string Watermark
{
get { return (string)GetValue(WatermarkProperty); }
set
{
SetValue(WatermarkProperty, value);
}
}
public string Text
{
get { return (string) GetValue(TextProperty); }
set{SetValue(TextProperty,value);}
}
private void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (TextChanged != null) TextChanged(this, e);
}
public void Clear()
{
textBox.Clear();
}
}
}
我不敢相信居然没有人发布Xceed的WPF扩展工具包——WatermarkTextBox。它工作得很好,并且是开源的,如果你想定制的话。
编辑:虽然仍然是开源的,但这个库现在只对非商业用途免费,请参阅价格和许可证。
如果水印的可见性不是取决于控件的焦点状态,而是取决于用户是否输入了任何文本,您可以将John Myczek的答案(从OnWatermarkChanged向下)更新为
static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var textbox = (TextBox)d;
textbox.Loaded += UpdateWatermark;
textbox.TextChanged += UpdateWatermark;
}
static void UpdateWatermark(object sender, RoutedEventArgs e) {
var textbox = (TextBox)sender;
var layer = AdornerLayer.GetAdornerLayer(textbox);
if (layer != null) {
if (textbox.Text == string.Empty) {
layer.Add(new WatermarkAdorner(textbox, GetWatermark(textbox)));
} else {
var adorners = layer.GetAdorners(textbox);
if (adorners == null) {
return;
}
foreach (var adorner in adorners) {
if (adorner is WatermarkAdorner) {
adorner.Visibility = Visibility.Hidden;
layer.Remove(adorner);
}
}
}
}
}
如果文本框在显示表单或绑定到Text属性时自动获得焦点,这就更有意义了。
同样,如果你的水印总是一个字符串,你需要水印的风格来匹配文本框的风格,那么在Adorner做:
contentPresenter = new ContentPresenter {
Content = new TextBlock {
Text = (string)watermark,
Foreground = Control.Foreground,
Background = Control.Background,
FontFamily = Control.FontFamily,
FontSize = Control.FontSize,
...
},
...
}
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何转换列表<字符串>列表<int>?