c#笔记--WPF文本框和密码框添加水印效果(背景文字提示)
文本框(TextBox)水印效果
显示效果:
方法一:验证触发器填充VisualBrush
创建一个可视画刷VisualBrush,使用触发器验证一下Text是否为空,使用VisualBrush填充TextBox的背景色
<TextBox Height="25" Width="180" HorizontalAlignment="Center" Margin="0 50 0 0">
<TextBox.Resources>
<VisualBrush x:Key="HelpBrush" TileMode="None" Opacity="0.3" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<TextBlock Text="请输入账号"/>
</VisualBrush.Visual>
</VisualBrush>
</TextBox.Resources>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
方法二:判断鼠标焦点填充SolidColorBrush
判断TextBox获取到焦点时文字消失,失去焦点时文字显示,在后台使用SolidColorBrush画刷填充
XAML代码(添加TextBox获取到焦点和失去焦点的事件):
<TextBox Name="tbxUser" GotFocus="TbxUser_GotFocus" Foreground="LightGray" LostFocus="TbxUser_LostFocus"
Height="25" Width="180" HorizontalAlignment="Center" Margin="0 20 0 0"></TextBox>
后台代码(由于窗口刚加载时没有判断焦点,所以在窗口加载时初始化填充,然后判断捕捉到鼠标焦点时取消填充,失去焦点时判断是否输入了文字,没输入则再次填充):
public MainWindow()
{
InitializeComponent();
tbxUser.Text = "请输入账号";
SolidColorBrush scb = new SolidColorBrush(Colors.LightGray);
tbxUser.Foreground = scb;
}
private void TbxUser_GotFocus(object sender, RoutedEventArgs e)
{
tbxUser.Text = "";
SolidColorBrush scb = new SolidColorBrush(Colors.Black);
tbxUser.Foreground = scb;
}
private void TbxUser_LostFocus(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(tbxUser.Text))
{
tbxUser.Text = "请输入账号";
SolidColorBrush scb = new SolidColorBrush(Colors.LightGray);
tbxUser.Foreground = scb;
}
}
两种方法的区别在于第一种鼠标点击TextBox时提示文字不会消失,当输入文字时才消失,第二种方法则是鼠标点击TextBox时则提示文字消失
密码框(PasswordBox)水印效果
显示效果:
由于密码框没有可以用于判断输入值非空的依赖属性,于是我们添加一个PasswordBoxMonitor类来监测密码框是否为空,继承与DependencyObject类;通过PasswordLength属性来判断密码框输入的内容长度是否为0来显示水印
需要引入的命名空间:
using System.Windows;
using System.Windows.Controls;
PasswordBoxMonitor类代码:
public class PasswordBoxMonitor : DependencyObject
{
public static bool GetIsMonitoring(DependencyObject obj)
{
return (bool)obj.GetValue(IsMonitoringProperty);
}
public static void SetIsMonitoring(DependencyObject obj, bool value)
{
obj.SetValue(IsMonitoringProperty, value);
}
public static readonly DependencyProperty IsMonitoringProperty =
DependencyProperty.RegisterAttached("IsMonitoring", typeof(bool), typeof(PasswordBoxMonitor), new UIPropertyMetadata(false, OnIsMonitoringChanged));
public static int GetPasswordLength(DependencyObject obj)
{
return (int)obj.GetValue(PasswordLengthProperty);
}
public static void SetPasswordLength(DependencyObject obj, int value)
{
obj.SetValue(PasswordLengthProperty, value);
}
public static readonly DependencyProperty PasswordLengthProperty =
DependencyProperty.RegisterAttached("PasswordLength", typeof(int), typeof(PasswordBoxMonitor), new UIPropertyMetadata(0));
private static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var pb = d as PasswordBox;
if (pb == null)
{
return;
}
if ((bool)e.NewValue)
{
pb.PasswordChanged += PasswordChanged;
}
else
{
pb.PasswordChanged -= PasswordChanged;
}
}
static void PasswordChanged(object sender, RoutedEventArgs e)
{
var pb = sender as PasswordBox;
if (pb == null)
{
return;
}
SetPasswordLength(pb, pb.Password.Length);
}
}
创建好类之后再使用重构的PasswordBox,需要在window中引用
xmlns:PasswordStyle="clr-namespace:你的项目名"
之后在PasswordBox样式中重写ControlTemplate 方法,添加一个TextBox覆盖掉密码框,当输入文字之后隐藏掉TextBox
XAML代码:
<PasswordBox VerticalAlignment="Center" Name="pb" HorizontalAlignment="Center"
VerticalContentAlignment="Center" Height="30" Width="220"
Margin="0 10 0 0">
<PasswordBox.Style>
<Style TargetType="PasswordBox">
<Setter Property="Height" Value="23"></Setter>
<Setter Property="HorizontalAlignment" Value="Left"></Setter>
<Setter Property="VerticalAlignment" Value="Top"></Setter>
<Setter Property="PasswordStyle:PasswordBoxMonitor.IsMonitoring" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Name="Bd" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<StackPanel Orientation="Horizontal" Visibility="Collapsed" Name="myStackPanel">
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="LightGray" Text=" 请输入密码"/>
</StackPanel>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Visibility" TargetName="myStackPanel" Value="Collapsed"/>
</Trigger>
<Trigger Property="PasswordStyle:PasswordBoxMonitor.PasswordLength" Value="0">
<Setter Property="Visibility" TargetName="myStackPanel" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</PasswordBox.Style>
</PasswordBox>
提示:写完之后可能会提示命名空间找不到,有时候是编译器没刷新过来,尝试编译运行一下就好了
♪(^∀^●)ノ