我怎么能把一些文本放入一个文本框,这将被自动删除时,用户键入的东西在它?
当前回答
我已经创建了一个简单的代码实现,它适用于WPF和Silverlight:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
public class TextBoxWatermarked : TextBox
{
#region [ Dependency Properties ]
public static DependencyProperty WatermarkProperty = DependencyProperty.Register
(
"Watermark",
typeof(string),
typeof(TextBoxWatermarked),
new PropertyMetadata(new PropertyChangedCallback(OnWatermarkChanged))
);
#endregion
#region [ Fields ]
private bool _isWatermarked;
private Binding _textBinding;
#endregion
#region [ Properties ]
protected new Brush Foreground
{
get { return base.Foreground; }
set { base.Foreground = value; }
}
public string Watermark
{
get { return (string)GetValue(WatermarkProperty); }
set { SetValue(WatermarkProperty, value); }
}
#endregion
#region [ .ctor ]
public TextBoxWatermarked()
{
Loaded += (s, ea) => ShowWatermark();
}
#endregion
#region [ Event Handlers ]
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
HideWatermark();
}
protected override void OnLostFocus(RoutedEventArgs e)
{
base.OnLostFocus(e);
ShowWatermark();
}
private static void OnWatermarkChanged(DependencyObject sender, DependencyPropertyChangedEventArgs ea)
{
var tbw = sender as TextBoxWatermarked;
if (tbw == null) return;
tbw.ShowWatermark();
}
#endregion
#region [ Methods ]
private void ShowWatermark()
{
if (string.IsNullOrEmpty(base.Text))
{
_isWatermarked = true;
base.Foreground = new SolidColorBrush(Colors.Gray);
var bindingExpression = GetBindingExpression(TextProperty);
_textBinding = bindingExpression == null ? null : bindingExpression.ParentBinding;
if (bindingExpression != null)
bindingExpression.UpdateSource();
SetBinding(TextProperty, new Binding());
base.Text = Watermark;
}
}
private void HideWatermark()
{
if (_isWatermarked)
{
_isWatermarked = false;
ClearValue(ForegroundProperty);
base.Text = "";
SetBinding(TextProperty, _textBinding ?? new Binding());
}
}
#endregion
}
用法:
<TextBoxWatermarked Watermark="Some text" />
其他回答
<TextBox x:Name="OrderTxt" HorizontalAlignment="Left" VerticalAlignment="Top" VerticalContentAlignment="Center" Margin="10,10,0,0" Width="188" Height="32"/>
<Label IsHitTestVisible="False" Content="Order number" DataContext="{Binding ElementName=OrderTxt}" Foreground="DarkGray">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Width" Value="{Binding Width}"/>
<Setter Property="Height" Value="{Binding Height}"/>
<Setter Property="Margin" Value="{Binding Margin}"/>
<Setter Property="VerticalAlignment" Value="{Binding VerticalAlignment}"/>
<Setter Property="HorizontalAlignment" Value="{Binding HorizontalAlignment}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
还有,看看这个答案。你可以用VisualBrush和Style中的一些触发器更容易地完成这一点:
<TextBox>
<TextBox.Style>
<Style TargetType="TextBox" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="Search" Foreground="LightGray" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
为了增加此样式的可重用性,您还可以创建一组附加属性来控制实际的提示横幅文本、颜色、方向等。
嗨,我把这个任务变成了一个行为。你只需要在文本框中添加这样的东西
<i:Interaction.Behaviors>
<Behaviors:TextBoxWatermarkBehavior Label="Test Watermark" LabelStyle="{StaticResource StyleWatermarkLabel}"/>
</i:Interaction.Behaviors>
你可以在这里找到我的博客文章
如果水印的可见性不是取决于控件的焦点状态,而是取决于用户是否输入了任何文本,您可以将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,
...
},
...
}
Telerik有一个控件叫做RadWatermarkTextBox专门解决这个问题。如果您正在使用Telerik控件,只需按以下方式使用即可
<telerik:RadWatermarkTextBox
Text="{Binding Path=MyTextBoxText}"
WatermarkContent="Please enter some text" />
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制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>?