您可以使用通常在App.xaml 中声明的样式以可重用的方式执行此操作。在这种风格中,您将控件模板替换为您自己的实现并将一些控件包装在一起。基本上,您从具有透明背景的普通TextBox 组成WatermarkTextBox,并在TextBox 后面放置一个带有标准文本的TextBlock 控件。此TextBlock 的Visibility 使用特定的TextInputToVisibilityConverter 绑定到TextBox,因此当TextBox 具有文本或仅具有焦点时它将消失。
虽然这可能看起来像很多代码,但您只需定义一次,就可以在任何需要的地方重复使用它,只需设置 TextBox 的样式
部分资源声明
xmlns:c="clr-namespace:YourNameSpace.Converters"
<SolidColorBrush x:Key="brushWatermarkBackground" Color="White" />
<SolidColorBrush x:Key="brushWatermarkForeground" Color="LightSteelBlue" />
<c:TextInputToVisibilityConverter x:Key="TextInputToVisibilityConverter" />
风格声明:
<Style x:Key="SearchTextBox" TargetType="{x:Type TextBox}">
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid Background="{StaticResource brushWatermarkBackground}">
<TextBlock Margin="5,5" Text="Search..."
Foreground="{StaticResource brushWatermarkForeground}" >
<TextBlock.Visibility>
<MultiBinding
Converter="{StaticResource TextInputToVisibilityConverter}">
<Binding RelativeSource="{RelativeSource
Mode=FindAncestor, AncestorType=TextBox}"
Path="Text.IsEmpty" />
<Binding RelativeSource="{RelativeSource
Mode=FindAncestor, AncestorType=TextBox}"
Path="IsFocused" />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
<Border x:Name="Border" Background="Transparent"
BorderBrush="{DynamicResource SolidBorderBrush}"
BorderThickness="1" Padding="2" CornerRadius="2">
<!-- The implementation places the Content into the
ScrollViewer. It must be named PART_ContentHost
for the control to function -->
<ScrollViewer Margin="0" x:Name="PART_ContentHost"
Style="{DynamicResource SimpleScrollViewer}"
Background="Transparent"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TextInputToVisibilityConverter 的实现,它只接受文本输入,转换为 bool 并将其转换为 Visibility。还考虑了焦点。
namespace YourNameSpace
{
public class TextInputToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values,
Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (values[0] is bool && values[1] is bool)
{
bool hasText = !(bool)values[0];
bool hasFocus = (bool)values[1];
if (hasFocus || hasText)
return Visibility.Collapsed;
}
return Visibility.Visible;
}
public object[] ConvertBack(object value,
Type[] targetTypes, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
现在所有基础设施都已就位。在您的视图/用户控件/窗口中,只需更改文本框的样式就可以了,您的水印文本框..
<TextBox Style="{DynamicResource SearchTextBox}" />