在WPF中需要顯示水印的效果,有時(shí)候需要顯示在TextBox上顯示類似水印的灰色提示文本占位符效果來作為提醒信息類似如下效果:

圖1. 水印顯示的效果
要實(shí)現(xiàn)這樣的效果有很多辦法,這里介紹一個(gè)最簡單的,就是在TextBox上疊加一個(gè)TextBlock來實(shí)現(xiàn)這個(gè)功能,這里對(duì)比顯示完全的實(shí)現(xiàn)過程:
- 原始的沒有占位符效果的代碼如下:
<StackPanel Orientation="Horizontal">
<Label Content="Print Ran_ge:"/>
<TextBox Text="{Binding PrintRange, UpdateSourceTrigger=PropertyChanged}" MinWidth="300" VerticalContentAlignment="Center" ToolTip="Serial number in format: 1,3-5,8" />
</StackPanel>
- 是輕松實(shí)現(xiàn)兩個(gè)控件疊加的效果,Grid是最簡單直接的,要顯示在上面的注意放在Grid里的后面部分,越前面越在底層,這里TextBlock在TextBox的后面,所以它顯示在TextBox的上面,就出現(xiàn)了如上圖1的效果:
<StackPanel Orientation="Horizontal" >
<Label Content="Print Ran_ge:"/>
<Grid>
<TextBox Text="{Binding PrintRange, UpdateSourceTrigger=PropertyChanged}" MinWidth="300" VerticalContentAlignment="Center" ToolTip="Serial number in format: 1,3-5,8" />
<TextBlock Text="Serial number in format: 1,3-5,8" Visibility="{Binding ShowPrintRangeWaterMark}" VerticalAlignment="Center" Foreground="Gray" Padding="5,0" IsHitTestVisible="False"/>
</Grid>
</StackPanel>
上面代碼兩個(gè)要點(diǎn):
a. <TextBox Text="{Binding PrintRange, UpdateSourceTrigger=PropertyChanged}",這個(gè)讓屬性改變的觸發(fā)實(shí)時(shí)發(fā)生,而不是在TextBox失去焦點(diǎn)才發(fā)生。
b. <TextBlock Text="Serial number in format: 1,3-5,8" Visibility="{Binding ShowPrintRangeWaterMark}" VerticalAlignment="Center" Foreground="Gray" Padding="5,0" IsHitTestVisible="False"/>,加粗部分讓TextBlock不響應(yīng)任何點(diǎn)擊或者輸入事件,它懸浮在那里,但它不影響下面的TextBox的鍵盤鼠標(biāo)的操作。
- 功能的實(shí)現(xiàn),功能的實(shí)現(xiàn)我們是通過兩個(gè)控件綁定的兩個(gè)屬性來實(shí)現(xiàn)的,一個(gè)是TextBox的
Text屬性,它綁定了其視圖模型的PrintRange屬性,一個(gè)是TextBlock的Visibility屬性,它綁定了其視圖模型的ShowPrintRangeWaterMark屬性。
代碼很簡單,打開視圖模型的類,添加兩個(gè)上面提到的屬性:
private string _printRange;
public string PrintRange
{
get => _printRange;
set
{
_printRange = value;
OnPropertyChanged(nameof(PrintRange));
OnPropertyChanged(nameof(ShowPrintRangeWaterMark));
}
}
public Visibility ShowPrintRangeWaterMark => string.IsNullOrEmpty(_printRange) ? Visibility.Visible : Visibility.Collapsed;
需要注意的是,這個(gè)視圖模型一定要實(shí)現(xiàn)INotifyPropertyChanged接口,就是要這些代碼:
public class MyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}