WPF TextBox和PasswordBox添加水印
作者:眾尋 发布时间:2021-09-30 16:06:02
标签:WPF,TextBox,PasswordBox,水印
本文实例为大家分享TextBox和PasswordBox加水印的方法,供大家参考,具体内容如下
Textbox加水印
Textbox加水印,需要一个VisualBrush和触发器验证Text是否为空,在空的时候设置背景的Brush就可以实现水印效果。
<TextBox Name="txtBoxName" Width="120" Height="23">
<TextBox.Resources>
<VisualBrush x:Key="HelpBrush" TileMode="None" Opacity="0.3" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<TextBlock FontStyle="Italic" Text="水印效果"/>
</VisualBrush.Visual>
</VisualBrush>
</TextBox.Resources>
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Height" Value="23"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
PasswordBox加水印
PasswordBox加水印,需要添加判断输入非空的依赖属性,因为PasswordBox本身没有这个属性。
通过一个PasswordLength函数判断密码框的长度是不是0,如果是0则显示背景水印,否则就隐藏。
属性部分代码,CS文件
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);
}
}
XMAL代码
<PasswordBox Name="pb" Width="120" VerticalAlignment="Bottom" Height="35">
<PasswordBox.Style>
<Style TargetType="PasswordBox">
<Setter Property="Height" Value="23"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="local: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="local:PasswordBoxMonitor.PasswordLength" Value="0">
<Setter Property="Visibility" TargetName="myStackPanel" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</PasswordBox.Style>
</PasswordBox>
效果图
2016-09-07 新增内容
将TextBlock暴露出来,做一个可以修改水印的Textbox控件
<TextBox x:Class="OracleCodeGenerator.watermarkTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OracleCodeGenerator"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Name="tb">
<TextBox.Resources>
<VisualBrush x:Key="HelpBrush" TileMode="None" Opacity="0.3" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<TextBlock Text="{Binding TbText,ElementName=tb}" FontStyle="Italic"/>
</VisualBrush.Visual>
</VisualBrush>
</TextBox.Resources>
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Height" Value="23"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
public partial class watermarkTextBox : TextBox
{
public watermarkTextBox()
{
InitializeComponent();
}
private string tbText;
public string TbText
{
get
{
return tbText;
}
set
{
tbText = value;
}
}
}
调用只有一句话
<local:watermarkTextBox Width="150" TbText="我是水印"/>
来源:http://www.cnblogs.com/ZXdeveloper/p/4807209.html


猜你喜欢
- 前言定时任务动态管理分为两种方式:方式一:Web前台配置Trigger触发器(关联Cron)、ThreadPoolTaskScheduler
- 布局中listview要覆盖标题栏 int mTouchSlop = ViewConfiguration.get(this).getScal
- Java爬取图片现在开始学习爬虫,对于爬虫的入门来说,图片相对来说是比较容易获取的,因为大部分图片都不是敏感数据,所以不会遇到什么反爬措施,
- 引入依赖 <dependency> <g
- 一、简介BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。实例化Bean做前置处理、后置处理二、接口定义
- 一、线程池使用场景•单个任务处理时间短•将需处理的任务数量大二、使用Java线程池好处1、使用new Thread()创建线程的弊端:•每次
- 原因如下: Delete()之后需要datatable.AccepteChanges()方法确认完全删除,因为Delete()只是将相应列的
- 应用启动数据初始化接口CommandLineRunner和Application详解在SpringBoot项目中创建组件类实现Command
- 原因用Java调用雪球的API,结果返回的是乱码,一番研究后发现是因为返回的数据使用了GZIP压缩,需要先解压才能得到正确数据。思路使用了G
- 介绍:淡入淡出动画(也称为“叠化”)逐渐淡出一个 View 或 ViewGroup,同时淡入另一个。此动画适用于您希望在应用中切换内容或视图
- 1、在设计初期阶段,应该要有意识的将不同的两层分离,比如考虑数据访问层、业务逻辑层、表示层之间建立外观模式,这样可以为子系统提供简单一致的接
- 本文实例讲述了C#判断访问来源是否为搜索引擎链接的方法。分享给大家供大家参考。具体分析如下:这段代码通过获取UrlReferrer判断访客是
- 现在,C#创建不规则窗体不是一件难事,下面总结一下:一、自定义窗体一般为规则的图形,如圆、椭圆等。做法:重写Form1_Paint事件(Fo
- 正文将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要
- 前言前不久遇到一个问题,是公司早期的基础库遇到的,其实很低级,但是还是记录下来。出错点是一个 IO 流的写入bug,我们项目会有一种专有的数
- 在一个项目中我们可能会需要用到相同的布局设计,如果都写在一个xml文件中,代码显得很冗余,并且可读性也很差,所以我们可以把相同布局的代码单独
- 1.类加载机制Java中的源码.java后缀文件会在运行前被编译成.class后缀文件,文件内的字节码的本质就是一个字节数组 ,它有特定的复
- Android 文件操作详解Android 的文件操作说白了就是Java的文件操作的处理。所以如果对Java的io文件操作比较熟
- 对于学习过C语言的朋友应该都知道,使用 malloc/calloc 等分配内存的函数时,一定要检查其返回值是否为“空指针”(亦即检查分配内存
- 要画这种圆形带阴影的头像,个人分解成三个图层1,先画头像边缘的渐变RadialGradient gradient = new RadialG