在文本框中提供一个描述,第一次输入后就消失。这应该为用户提供一点帮助,告诉他应该在文本字段中输入什么,例如水印。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Add TargetType="{x:Type TextBox}" to make this style the default for all TextBoxes. -->
<Style x:Key="WatermarkedTextBox" >
<Setter Property="Control.Template" >
<Setter.Value>
<ControlTemplate TargetType="TextBox" >
<!-- Template derived from Default TextBoxBase. -->
<!-- Added the Label InternalWatermarkLabel together with the surrounding Grid. -->
<Grid>
<mwt:ListBoxChrome Name="Bd"
Background="{TemplateBinding Panel.Background}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
BorderThickness="{TemplateBinding Border.BorderThickness}"
RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
RenderFocused="{TemplateBinding UIElement.IsKeyboardFocusWithin}"
SnapsToDevicePixels="True">
<ScrollViewer Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
/>
</mwt:ListBoxChrome>
<Label x:Name="InternalWatermarkLabel"
Content="{TemplateBinding Tag}"
Visibility="Collapsed" Focusable="False"
Foreground="Silver"
Background="Transparent"
/>
</Grid>
<ControlTemplate.Triggers>
<!-- The multitrigger is responsible for showing and hiding the watermark. -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False" />
<Condition Property="Text" Value="" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Visibility" TargetName="InternalWatermarkLabel"
Value="Visible" />
</MultiTrigger.Setters>
</MultiTrigger>
<!-- This trigger mimics the default behavior. -->
<Trigger Property="UIElement.IsEnabled" Value="False" >
<Setter Property="Panel.Background" TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="TextElement.Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
这是MainWindow.xaml文件内容:
<Window x:Class="WpfWatermark.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Watermark, the XAML way" Height="120" Width="400" >
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WatermarkResource.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Content="Textbox with Watermark:" />
<!-- The FrameworkElement.Tag Property of .NET 4 is used to store the -->
<!-- watermark information as the custom information about this element. -->
<TextBox Grid.Row="0" Grid.Column="1"
Tag="This is the Watermark Text."
Style="{StaticResource WatermarkedTextBox}"
/>
<Label Grid.Row="1" Content="A normal Textbox:" />
<TextBox Grid.Row="1" Grid.Column="1" />
</Grid>
</Window>
这是一个正在运行的应用程序的截图,其中水印是可见的。
这是带有一些文本的截图,其中水印被隐藏了。
这是基于.Net 4版本的Christians解决方案,它也不需要使用Aero库:
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
<TextBlock x:Name="InternalWatermarkLabel"
Text="{TemplateBinding Tag}"
Visibility="Collapsed" Focusable="False"
VerticalAlignment="Top" Margin=" 5 1 0 0"
Foreground="Silver"
Background="Transparent"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False" />
<Condition Property="Text" Value="" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Visibility" TargetName="InternalWatermarkLabel"
Value="Visible" />
</MultiTrigger.Setters>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
这里是一个仅使用XAML的解决方案,采用了相对基础的“机制”。
注意:可能有更好和/或更优雅的方法来做这件事,但这是我通过试验和结合在这个站点上发现的内容而得到的。
我认为它非常明确易懂,可以对一些人有用...
欢迎针对任何问题或可以改进的地方进行评论。
<Grid>
<TextBox Name="TheField"
HorizontalAlignment="Center"
VerticalAlignment="Center"
MinWidth="170"
Background="Transparent"
Foreground="Black"
Margin="5,2,5,2"
BorderThickness="0"
FontSize="10"
Text="{Binding THE_BOUNDED_PROPERTY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox HorizontalAlignment="Center"
VerticalAlignment="Center"
MinWidth="170"
Foreground="#FF808080"
Margin="5,2,5,2"
IsHitTestVisible="False"
BorderThickness="0"
FontStyle="Italic"
FontSize="10"
Text="THE DEFAULT TEXT">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=TheField, Path=IsKeyboardFocusWithin}" Value="False"/>
<Condition Binding="{Binding ElementName=TheField, Path=Text.IsEmpty}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible"/>
</MultiDataTrigger>
<DataTrigger Binding="{Binding ElementName=TheField, Path=IsKeyboardFocusWithin}" Value="True">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=TheField, Path=Text.IsEmpty}" Value="False">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
对于任何对此问题感兴趣的人,请查看材料设计 (http://materialdesigninxaml.net/)。
通过这个库,做到这一点真的很容易:
<TextBox
x:Name="SuggestedTextBox"
materialDesign:HintAssist.Hint="My suggestion" />