WPF中带水印的Textbox
很多时候我们都希望通过水印来告诉用户这里该填什么样格式的数据,那么我们就希望有这样的一个控件。
为了方便起见,先定义一个依赖属性专门来存放水印中显示的字符串。
public sealed class TextBoxWithMark : TextBox { public static readonly DependencyProperty WaterMarksProperty = DependencyProperty.Register( "WaterMarks", typeof(string), typeof(TextBoxWithMark), new PropertyMetadata(default(string))); public string WaterMarks { get { return (string)GetValue(WaterMarksProperty); } set { SetValue(WaterMarksProperty, value); } } }
在引用中引用当前的命名空间
xmlns:local="clr-namespace:Example"
引入转换器
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
现在的预想是当用户输入字符时水印消失,字串为空时水印出现,可以用事件来做,但是显然不太合适,因此我们考虑用触发器来做,可以减少很多不必要的代码逻辑。
实现control template
<ControlTemplate x:Key="WaterMarkBox" TargetType="local:TextBoxWithMark"> <Grid Margin="2"> <Label VerticalAlignment="Center" Margin="2,0,0,0" Content="{TemplateBinding WaterMarks}" Foreground="Gray" FontStyle="Italic" Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}, UpdateSourceTrigger=PropertyChanged}"> </Label> <TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Background="Transparent" VerticalContentAlignment="Center"/> </Grid> </ControlTemplate>
如果Text是空的则隐藏掉label,UpdateSourceTrigger=PropertyChanged这个很重要,否则要丢失焦点才引发事件不符合我们的需求。
现在在其他地方可以很方便的来使用这个控件
<local:TextBoxWithMark x:Name="TbCc" WaterMarks="input hint" Template="{StaticResource WaterMarkBox}"/>