WPF 密码框水印与明文切换

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF 密码框水印与明文切换相关的知识,希望对你有一定的参考价值。

WPF开发者QQ群: 340500857 

欢迎转发、分享、点赞、在看,谢谢~。  

效果预览(更多效果请下载源码体验):

一、PasswordWithPlainText.xaml 代码如下

<UserControl x:Class="WpfPasswrod.CustomControls.PasswordWithPlainText"
             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:input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
             xmlns:local="clr-namespace:WpfPasswrod.CustomControls"
             Name="uc" Foreground="Black"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <ResourceDictionary>
            <VisualBrush x:Key="HelpBrush" TileMode="None" Opacity="0.3" Stretch="None" AlignmentY="Center" 
                     AlignmentX="{Binding AlignmentX,ElementName=uc}"
                     ViewportUnits="RelativeToBoundingBox">
                <VisualBrush.Viewport>
                    <Rect X="0.01" Y="0" Width="1" Height="1"></Rect>
                </VisualBrush.Viewport>
                <VisualBrush.Visual>
                    <TextBlock VerticalAlignment="Stretch" HorizontalAlignment="Left" 
                               TextAlignment="{Binding TextAlignment,ElementName=uc}"
                           Foreground="{Binding Foreground,ElementName=uc}"
                           Text="{Binding Hint,ElementName=uc}"
                           FontSize="{Binding FontSize,ElementName=uc}"/>
                </VisualBrush.Visual>
            </VisualBrush>


            <SolidColorBrush x:Key="ImageToggleButton.Static.Background" Color="#FFDDDDDD"/>
            <SolidColorBrush x:Key="ImageToggleButton.Static.Border" Color="#FF707070"/>
            <SolidColorBrush x:Key="ImageToggleButton.MouseOver.Background" Color="#FFBEE6FD"/>
            <SolidColorBrush x:Key="ImageToggleButton.IsChecked.Background" Color="#FFBEE6FD"/>




            <Style TargetType="{x:Type local:ImageToggleButton}">
                <Setter Property="SnapsToDevicePixels" Value="true"/>
                <Setter Property="UseLayoutRounding" Value="True"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="Background" Value="{StaticResource ImageToggleButton.Static.Background}"/>
                <Setter Property="BorderBrush" Value="{StaticResource ImageToggleButton.Static.Border}"/>
                <Setter Property="Cursor" Value="Hand"/>


                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:ImageToggleButton}">
                            <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
                Background="{TemplateBinding Background}"
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                UseLayoutRounding="True"
                CornerRadius="{Binding Path=CornerRadius, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                                <Grid>
                                    <Image x:Name="image"  Focusable="False" Margin="0,1,0,0"
                       Source="{Binding NormalImage, RelativeSource={RelativeSource TemplatedParent}}"
                       HorizontalAlignment="Center" VerticalAlignment="Center" Height="20" Width="20"/>
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsChecked" Value="true">
                                    <Setter TargetName="border" Property="Background" Value="{StaticResource ImageToggleButton.IsChecked.Background}"/>
                                    <Setter TargetName="image" Property="Source" Value="{Binding UnImage, RelativeSource={RelativeSource TemplatedParent}}"/>
                                </Trigger>
                                
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter TargetName="border" Property="Background" Value="{StaticResource ImageToggleButton.MouseOver.Background}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
</Style>


        </ResourceDictionary>
    </UserControl.Resources>
    <Border BorderThickness="1" BorderBrush="{Binding BorderBrush,ElementName=uc}"
            CornerRadius="{Binding CornerRadius,ElementName=uc}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Image Source="{Binding IconImage,ElementName=uc}" Margin="4,0"
                   HorizontalAlignment="Center" VerticalAlignment="Center" Height="20" Width="20"/>
            <TextBox Name="tbPlainText" Grid.Column="1" 
                     Text="{Binding Password,Mode=TwoWay,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:PasswordWithPlainText}}"
                 FontSize="{Binding FontSize,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:PasswordWithPlainText}}" 
                     TextAlignment="{Binding AlignmentX,ElementName=uc}"
                 BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Center" Visibility="Collapsed"
                 input:InputMethod.IsInputMethodEnabled="False" 
                 Foreground="{Binding Foreground,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:PasswordWithPlainText}}"
                 CaretBrush="{Binding CaretBrush,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:PasswordWithPlainText}}">
                <TextBox.Style>
                    <Style TargetType="TextBox">
                        <Setter Property="Background" Value="{Binding ElementName=textBox, Path=Background}"/>
                        <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 Name="pwdCiphertext"  Grid.Column="1" local:PasswordBoxHelper.Attach="True" 
                         TextBlock.TextAlignment="{Binding AlignmentX,ElementName=uc}"
                     local:PasswordBoxHelper.Password="{Binding Password,Mode=TwoWay,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:PasswordWithPlainText}}"
                     FontSize="{Binding FontSize,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:PasswordWithPlainText}}"
                     BorderThickness="0" Background="{StaticResource HelpBrush}" HorizontalAlignment="Stretch" VerticalAlignment="Center"
                     PasswordChanged="pwdCiphertext_PasswordChanged"
                     Foreground="{Binding Foreground,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:PasswordWithPlainText}}"
                     CaretBrush="{Binding CaretBrush,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:PasswordWithPlainText}}"/>


              <local:ImageToggleButton Grid.Column="2" Width="30"
                                    NormalImage="/WpfPasswrod;component/Resources/Eye_50px.png"
                                    UnImage="/WpfPasswrod;component/Resources/Invisible_50px.png"
                                   Checked="ImageToggleButton_Checked"
                                  Unchecked="ImageToggleButton_Unchecked"/>
        </Grid>
    </Border>
    
</UserControl>

二、PasswordWithPlainText.cs.xaml 代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;


namespace WpfPasswrod.CustomControls
{
    /// <summary>
    /// PasswordWithPlainText.xaml 的交互逻辑
    /// </summary>
    public partial class PasswordWithPlainText : UserControl
    {
        public PasswordWithPlainText()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 图标
        /// </summary>
        public static readonly DependencyProperty IconImageProperty =
                             DependencyProperty.Register("IconImage", typeof(ImageSource), typeof(PasswordWithPlainText), new PropertyMetadata(new BitmapImage(new Uri("pack://application:,,,/Resources/Lock_48px.png"))));
        /// <summary>
        /// 图标
        /// </summary>
        public ImageSource IconImage
        {
            get { return (ImageSource)GetValue(IconImageProperty); }
            set { SetValue(IconImageProperty, value); }
        }
        /// <summary>
        /// 文本框提示文字
        /// </summary>
        public string Hint
        {
            get { return (string)GetValue(HintProperty); }
            set { SetValue(HintProperty, value); }
        }
        // Using a DependencyProperty as the backing store for Hint.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HintProperty =
            DependencyProperty.Register("Hint", typeof(string), typeof(PasswordWithPlainText), new PropertyMetadata(null));
        /// <summary>
        /// 获取或设置水印背景的水平对齐方式
        /// </summary>
        public AlignmentX AlignmentX
        {
            get { return (AlignmentX)GetValue(AlignmentXProperty); }
            set { SetValue(AlignmentXProperty, value); }
        }


        // Using a DependencyProperty as the backing store for AlignmentX.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AlignmentXProperty =
            DependencyProperty.Register("AlignmentX", typeof(AlignmentX), typeof(PasswordWithPlainText), new PropertyMetadata(AlignmentX.Left));
        /// <summary>
        /// 获取或设置密码
        /// </summary>
        public string Password
        {
            get { return (string)GetValue(PasswordProperty); }
            set { SetValue(PasswordProperty, value); }
        }


        // Using a DependencyProperty as the backing store for Password.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PasswordProperty =
            DependencyProperty.Register("Password", typeof(string), typeof(PasswordWithPlainText), new PropertyMetadata(null));
        /// <summary>
        /// 获取或设置光标颜色
        /// </summary>
        public Brush CaretBrush
        {
            get { return (Brush)GetValue(CaretBrushProperty); }
            set { SetValue(CaretBrushProperty, value); }
        }


        // Using a DependencyProperty as the backing store for CaretBrush.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CaretBrushProperty =
            DependencyProperty.Register("CaretBrush", typeof(Brush), typeof(PasswordWithPlainText), new PropertyMetadata(Brushes.Black));


        /// <summary>
        /// 获取或设置光标颜色
        /// </summary>
        public Brush BorderBrush
        {
            get { return (Brush)GetValue(BorderBrushProperty); }
            set { SetValue(BorderBrushProperty, value); }
        }


        // Using a DependencyProperty as the backing store for CaretBrush.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BorderBrushProperty =
            DependencyProperty.Register("BorderBrush", typeof(Brush), typeof(PasswordWithPlainText), new PropertyMetadata(Brushes.Black));




        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(PasswordWithPlainText),
                                                                            new PropertyMetadata(new CornerRadius(0, 0, 0, 0), OnCornerRadiusChanged));
        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
            set
            {
                SetValue(CornerRadiusProperty, value);
            }
        }


        private static void OnCornerRadiusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CornerRadius cornerRadius = new CornerRadius();
            cornerRadius = (CornerRadius)e.NewValue;
        }


        /// <summary>
        /// 切换成明文
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// 
       
       private void ImageToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            pwdCiphertext.Visibility = Visibility.Collapsed;
            tbPlainText.Visibility = Visibility.Visible;
        }
        /// <summary>
        /// 切换成密文
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
          private void ImageToggleButton_Unchecked(object sender, RoutedEventArgs e)
        {
            pwdCiphertext.Visibility = Visibility.Visible;
            tbPlainText.Visibility = Visibility.Collapsed;
        }
        private void pwdCiphertext_PasswordChanged(object sender, RoutedEventArgs e)
        {
            PasswordBox pwd = sender as PasswordBox;
            if (pwd != null)
            {
                if (!string.IsNullOrEmpty(pwd.Password))
                {
                    pwd.Background = Brushes.Transparent;
                }
                else
                {
                    pwd.Background = (Brush)FindResource("HelpBrush");
                }
            }
        }


       
    }
}


源码地址

github:https://github.com/yanjinhuagood/WPFDevelopers.git

gitee:https://gitee.com/yanjinhua/WPFDevelopers.git

WPF开发者QQ群: 340500857 

blogs: https://www.cnblogs.com/yanjinhua

Github:https://github.com/yanjinhuagood

出处:https://www.cnblogs.com/yanjinhua

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载请著名作者 出处 https://github.com/yanjinhuagood

以上是关于WPF 密码框水印与明文切换的主要内容,如果未能解决你的问题,请参考以下文章

WPF自定义控件与样式-TextBox & RichTextBox & PasswordBox样式水印Label标签功能扩展

WPF之TextBox和PasswordBox水印效果

密码明文密文切换

WPF 自定义控件并使用(例如带水印和字体图标的文本框)

wpf passwobox 添加水印

WPF的TextBox水印效果详解