之前有做过wpf texbox添加水印,这个并不难 重写一下样式就可以了,今天用到了passwordbox 添加水印的时候 发现还是有点难度的。

这个难度就在于如何去取password的长度来控制水印文本的显隐。其实可以用附加依赖项属性去搞定,一个控制水印文本 一个控制显示 一个用来获取密码长度

废话不多说 直接上代码吧

附加依赖项属性代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls; namespace pwdwartmask.Attach
{
public class AttachProp
{
public static readonly DependencyProperty WaterMaskProperty = DependencyProperty.RegisterAttached(
"WaterMask", typeof(string), typeof(AttachProp), new PropertyMetadata(default(string))); public static void SetWaterMask(DependencyObject element, string value)
{
element.SetValue(WaterMaskProperty, value);
} public static string GetWaterMask(DependencyObject element)
{
return (string) element.GetValue(WaterMaskProperty);
} public static readonly DependencyProperty PasswordLengthProperty = DependencyProperty.RegisterAttached(
"PasswordLength", typeof(int), typeof(AttachProp), new PropertyMetadata(default(int))); public static void SetPasswordLength(DependencyObject element, int value)
{
element.SetValue(PasswordLengthProperty, value);
} public static int GetPasswordLength(DependencyObject element)
{
return (int) element.GetValue(PasswordLengthProperty);
} public static readonly DependencyProperty OpenWaterMaskProperty = DependencyProperty.RegisterAttached(
"OpenWaterMask", typeof(bool), typeof(AttachProp), new PropertyMetadata(false,OpenWaterCallBack)); public static void SetOpenWaterMask(DependencyObject element, bool value)
{
element.SetValue(OpenWaterMaskProperty, value);
} public static int GetOpenWaterMask(DependencyObject element)
{
return (int)element.GetValue(PasswordLengthProperty);
} public static void OpenWaterCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is PasswordBox pwd)
{
if ((bool) e.NewValue)
{
pwd.PasswordChanged += Pwd_PasswordChanged;
}
else
{
pwd.PasswordChanged -= Pwd_PasswordChanged;
}
}
} private static void Pwd_PasswordChanged(object sender, RoutedEventArgs e)
{
if (sender is PasswordBox pb)
{
SetPasswordLength(pb,pb.Password.Length);
}
}
}
}

前端样式代码:

 <SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>
<Style x:Key="pwd_style" TargetType="{x:Type PasswordBox}">
<Setter Property="PasswordChar" Value="●"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="attach:AttachProp.WaterMask" Value="Test"></Setter>
<Setter Property="attach:AttachProp.OpenWaterMask" Value="true"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
<TextBlock x:Name="PART_WaterMask" Visibility="Collapsed" VerticalAlignment="Center" Foreground="Coral" FontSize="{TemplateBinding FontSize}" Text="{TemplateBinding attach:AttachProp.WaterMask }"></TextBlock>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="attach:AttachProp.PasswordLength" Value="0"></Condition>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Visibility" Value="Visible" TargetName="PART_WaterMask"></Setter>
</MultiTrigger.Setters>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_WaterMask"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>

如果有用到的可以自己修改自己需要的属性

效果如下

wpf passwobox 添加水印的更多相关文章

  1. WPF DatePicker 添加水印效果

    这个控件没有水印属性,依然使用依赖属性解决 public class DatePickerHelper { public static object GetWatermark(DependencyOb ...

  2. WPF文本框密码框添加水印效果

    WPF文本框密码框添加水印效果 来源: 阅读:559 时间:2014-12-31 分享: 0 按照惯例,先看下效果 文本框水印 文本框水印相对简单,不需要重写模板,仅仅需要一个VisualBrush ...

  3. WPF 文本框添加水印效果

    有的时候我们需要为我们的WPF文本框TextBox控件添加一个显示水印的效果来增强用户体验,比如登陆的时候提示输入用户名,输入密码等情形.如下图所示: 这个时候我们除了可以修改TextBox控件的控件 ...

  4. WPF 之 文本框及密码框添加水印效果

    1.文本框添加水印效果 文本框水印相对简单,不需要重写模板,仅仅需要一个 VisualBrush 和触发器验证一下Text是否为空即可. <TextBox Name="txtSerac ...

  5. WPF 为 PasswordBox 控件添加水印,最低级版

    原因也很直接,老板需要,一开始为TextBox发愁,就找了这个控件凑合用,至于版权什么的,内部工具也不卖钱,而且我不懂英文,也就无视了: Extended WPF Toolkit™ Community ...

  6. 【WPF系列】Textbox

    Style定义实例 给Textbox定义一个阴影效果. <Style x:Key="{x:Type TextBox}" TargetType="{x:Type Te ...

  7. wpf采用Xps实现文档显示、套打功能(原创)

    近期的一个项目需对数据进行套打,用户要求现场不允许安装office.页面预览显示必须要与文档完全一致,xps文档来对数据进行处理.Wpf的DocumentView 控件可以直接将数据进行显示,xps也 ...

  8. 【WPF】学习笔记(三)——这个家伙跟电子签名板有个约定

    这篇博客依旧是以电子签名板为基础而展开的,主要是对前文([WPF]学习笔记(一)--做一个简单的电子签名板)存在的部分问题进行解释,以及部分小功能的添加.由于这篇博客是建立在学习笔记一的基础上的,所以 ...

  9. WPF自定义控件(一)の控件分类

    一.什么是控件(Controls) 控件是指对数据和方法的封装.控件可以有自己的属性和方法,其中属性是控件数据的简单访问者,方法则是控件的一些简单而可见的功能.控件创建过程包括设计.开发.调试(就是所 ...

随机推荐

  1. poj 2229 【完全背包dp】【递推dp】

    poj 2229 Sumsets Time Limit: 2000MS   Memory Limit: 200000K Total Submissions: 21281   Accepted: 828 ...

  2. Spark in action on Kubernetes - 存储篇(一)

    前言 在上篇文章中,我们分析了Spark Operator内部的机制,今天我们会讨论一个在大数据领域中最重要的话题 - 存储.大数据已经无声无息的融入了每个人的生活中.大到旅游买房,小到外卖打车,都可 ...

  3. 在dva框架和create-react-app创建出来的框架中修饰器语法与按需加载引入antd分别配置

    按需加载需要的包  babel-plugin-import    装饰器语法需要的包  @babel/plugin-proposal-decorators dva框架 将.webpackrc  改成. ...

  4. UVa 825【简单dp,递推】

    UVa 825 题意:给定一个网格图(街道图),其中有一些交叉路口点不能走.问从西北角走到东南角最短走法有多少种.(好像没看到给数据范围...) 简单的递推吧,当然也就是最简单的动归了.显然最短路长度 ...

  5. ADT上跑java application

    Invalid layout of java.lang.String at value## A fatal error has been detected by the Java Runtime En ...

  6. SP2-0642: SQL*Plus internal error state 2130, context 0:0:0

    ..experience, Working case SP2-0642: SQL*Plus internal error state 2130, context 0:0:0 2016-10-09 没有 ...

  7. 2018-7-5-dotnet-设计规范-·-抽象定义

    title author date CreateTime categories dotnet 设计规范 · 抽象定义 lindexi 2018-07-05 15:48:20 +0800 2018-2- ...

  8. 初识 Knative: 跨平台的 Serverless 编排框架

    Knative 是什么 Knative 是 Google 在 2018 的 Google Cloud Next 大会上发布的一款基于 Kubernetes 的 Serverless 框架.Knativ ...

  9. 如何用phpmyadmin导入大容量.sql文件,直接使用cmd命令进行导入

    很多使用php+mysql建站的站长朋友们,经常要用到phpMyAdmin数据库管理工具备份和恢复数据库,当站点运行很久的时候,MySQL数据库会非常大,当站点碰到问题时,需要使用phpMyAdmin ...

  10. 神经网络为什么需要多次epoch

    Δw(t)=−ε ∂w(t)∂E​ +αΔw(t−1)(9) 我们知道反向传播每次迭代的效果是这样的:w=w+Δw(t) w=w+\Delta w(t)w=w+Δw(t) 我们知道,每条训练数据都会导 ...