我怎么能把一些文本放入一个文本框,这将被自动删除时,用户键入的东西在它?
当前回答
<TextBox Grid.Column="0" Name="TextBox_SearchBar" AcceptsReturn="False" AcceptsTab="False" TextWrapping="Wrap" KeyUp="TextBox_SearchBar_KeyUp" />
<TextBox Grid.Column="0" Name="TextBox_Watermark" Text="Search Test Sets" Foreground="Gray" GotFocus="TextBox_Watermark_GotFocus" />
private void TextBox_Watermark_GotFocus( object sender, RoutedEventArgs e ) {
TextBox_Watermark.Visibility = Visibility.Hidden;
TextBox_SearchBar.Focus();
}
这将创建两个文本框,一个用于接收水印的字段,另一个用于水印。接收水印的字段可以是ComboBox或其他控件(只要您获得正确的对齐并相应地获得焦点)。
水印必须是一个文本框或其他控制,可以获得焦点(TextBlock不能获得焦点,因为我学会了艰难的方式)。当水印文本框得到焦点,它隐藏自己,并给予访问其他文本框。
如果你想在搜索栏文本框失去焦点后重新显示水印,只需添加一个LostFocus事件处理程序到TextBox_SearchBar检查输入并切换TextBox_Watermark可见性为隐藏或可见,相应地。
其他回答
嗨,我把这个任务变成了一个行为。你只需要在文本框中添加这样的东西
<i:Interaction.Behaviors>
<Behaviors:TextBoxWatermarkBehavior Label="Test Watermark" LabelStyle="{StaticResource StyleWatermarkLabel}"/>
</i:Interaction.Behaviors>
你可以在这里找到我的博客文章
好吧,这是我的:不一定是最好的,但因为它很简单,很容易编辑到你的口味。
<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();
}
}
}
还有,看看这个答案。你可以用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>
为了增加此样式的可重用性,您还可以创建一组附加属性来控制实际的提示横幅文本、颜色、方向等。
<TextBox Controls:TextBoxHelper.Watermark="Watermark"/>
添加mahapps。地铁到你的项目。 将带有上述代码的文本框添加到窗口中。
如果水印的可见性不是取决于控件的焦点状态,而是取决于用户是否输入了任何文本,您可以将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,
...
},
...
}