我怎么能把一些文本放入一个文本框,这将被自动删除时,用户键入的东西在它?
当前回答
好吧,这是我的:不一定是最好的,但因为它很简单,很容易编辑到你的口味。
<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();
}
}
}
其他回答
当使用@john-myczek的代码绑定文本框时,我遇到了一些困难。由于TextBox在更新时不会引发焦点事件,水印将在新文本下面保持可见。为了解决这个问题,我简单地添加了另一个事件处理程序:
if (d is ComboBox || d is TextBox)
{
control.GotKeyboardFocus += Control_GotKeyboardFocus;
control.LostKeyboardFocus += Control_Loaded;
if (d is TextBox)
(d as TextBox).TextChanged += Control_TextChanged;
}
private static void Control_TextChanged(object sender, RoutedEventArgs e)
{
var tb = (TextBox)sender;
if (ShouldShowWatermark(tb))
{
ShowWatermark(tb);
}
else
{
RemoveWatermark(tb);
}
}
该技术使用Background属性来显示/隐藏占位符文本框。 占位符显示事件时,文本框有焦点
工作原理:
当为空时,文本框背景设置为透明以显示占位符文本。 当不空背景设置为白色,以掩盖占位符文本。
这里有一个基本的例子。出于我自己的目的,我把它变成了一个UserControl。
<Grid>
<Grid.Resources>
<ux:NotEmptyConverter x:Key="NotEmptyConverter" />
<Style TargetType="{x:Type Control}" x:Key="DefaultStyle">
<Setter Property="FontSize" Value="20" />
<Setter Property="Margin" Value="10"/>
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="VerticalContentAlignment" Value="Center"></Setter>
</Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultStyle}"></Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="Placeholder Text Is Here" Foreground="DarkGray" />
<TextBox Grid.Row="0" Name="TextBoxEdit"
Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<TextBox.Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=FirstName.Length, FallbackValue=0, TargetNullValue=0}" Value="0">
<Setter Property="Background" Value="Transparent"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=FirstName, FallbackValue=0, TargetNullValue=0, Converter={StaticResource NotEmptyConverter}}" Value="false">
<Setter Property="Background" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
下面是ValueConverter,用于检测DataTrigger中的非空字符串。
public class NotEmptyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var s = value as string;
return string.IsNullOrEmpty(s);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
好吧,这是我的:不一定是最好的,但因为它很简单,很容易编辑到你的口味。
<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();
}
}
}
最简单的方法水印的文本框
<Window.Resources>
<Style x:Key="MyWaterMarkStyle" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border Background="White" BorderBrush="#FF7D8683" BorderThickness="1"/>
<ScrollViewer x:Name="PART_ContentHost" Margin="5,0,0,0" VerticalAlignment="Center" />
<Label Margin="5,0,0,0" x:Name="WaterMarkLabel" Content="{TemplateBinding Tag}" VerticalAlignment="Center"
Visibility="Collapsed" Foreground="Gray" FontFamily="Arial"/>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value=""/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="WaterMarkLabel" Value="Visible"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
并添加文本框StaticResource样式
<TextBox
Style="{StaticResource MyWaterMarkStyle}"
Tag="Search Category"
Grid.Row="0"
Text="{Binding CategorySearch,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
TextSearch.Text="Search Category"
>
我不敢相信居然没有人发布Xceed的WPF扩展工具包——WatermarkTextBox。它工作得很好,并且是开源的,如果你想定制的话。
编辑:虽然仍然是开源的,但这个库现在只对非商业用途免费,请参阅价格和许可证。
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制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>?