ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

WPF PasswordBox控件使用

2022-06-26 23:03:08  阅读:188  来源: 互联网

标签:SecureString 控件 string PasswordBox System pb WPF Password


一、PasswordBox的SecurePassword属性

正常的String类型值,在脱离开作用域之后,其值在内存中并不会被立即销毁,这时如果有人恶意扫描你的内存,程序中所保存的机密信息就会暴露;于是就有了System.Security.SecureString,SecureString表示一个应保密的文本,它在初始化时就已被加密,并且脱离作用域后会被立即销毁。PasswordBox提供了SecurePassword属性,该属性提供的是一个SecureString类型,SecureString类型转换为string类型如下所示:

 IntPtr p = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(this.LoginPasswordBox.SecurePassword);
 string password = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(p);

二、PasswordBox的密码明文展示样式实现

由于Password属性不是依赖属性,所以要实现密码的明文展示需要通过附加属性来实现,具体代码如下所示:

20220626_160232_

 public class PasswordBoxAttached
    {
        public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordBoxAttached), new PropertyMetadata("", PasswordPropertyChangedCallback));
        public static string GetPassword(DependencyObject obj)
        {
            return (string)obj.GetValue(PasswordProperty);
        }
        public static void SetPassword(DependencyObject obj, string value)
        {
            obj.SetValue(PasswordProperty, value);
        }
        private static void PasswordPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is System.Windows.Controls.PasswordBox pb)
            {
                pb.Password = e.NewValue.ToString();
                pb.GetType().GetMethod("Select", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(pb, new object[] { pb.Password.Length, 0 });
            }
        }
    }
 <Window.Resources>
        <Style x:Key="ToggleButtonStyle" TargetType="ToggleButton">
            <Setter Property="Margin" Value="5,0"></Setter>
            <Setter Property="Background" Value="Transparent"></Setter>
            <Setter Property="BorderThickness" Value="0"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ToggleButton">
                        <Image x:Name="IconImage" Source="Resources/eye_close.png"></Image>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter TargetName="IconImage" Property="Source" Value="Resources/eye_open.png"></Setter>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="IconImage" Property="Source" Value="Resources/eye_open.png"></Setter>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="PasswordBox">
            <Setter Property="VerticalContentAlignment" Value="Center"></Setter>
            <Setter Property="Padding" Value="5,0"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="PasswordBox">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="4">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                    <ColumnDefinition Width="32"></ColumnDefinition>
                                </Grid.ColumnDefinitions>
                                <ScrollViewer Grid.Column="0" x:Name="PART_ContentHost"></ScrollViewer>
                                <TextBlock  Grid.Column="0" x:Name="MessageTextBlock"
                                           Text="{TemplateBinding Tag}"
                                           FontSize="{TemplateBinding FontSize}"
                                           Foreground="{TemplateBinding Foreground}"
                                           Padding="{TemplateBinding Padding}"
                                           VerticalAlignment="Center"
                                           Visibility="Hidden"></TextBlock>
                                <TextBox Grid.Column="0" VerticalContentAlignment="Center"
                                         BorderThickness="0" Visibility="Hidden"
                                         FontSize="{TemplateBinding FontSize}"
                                         Foreground="{TemplateBinding Foreground}"
                                         Margin="{TemplateBinding Padding}"
                                         Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=PasswordBox}, Path=(local:PasswordBoxAttached.Password)}"
                                         x:Name="PasswordTextBox"></TextBox>
                                <ToggleButton Grid.Column="1" x:Name="CheckedToggleButton" Focusable="False" 
                                              Style="{StaticResource ToggleButtonStyle}"></ToggleButton>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsKeyboardFocused" Value="False"></Condition>
                                    <Condition Property="local:PasswordBoxAttached.Password" Value=""></Condition>
                                </MultiTrigger.Conditions>
                                <Setter TargetName="MessageTextBlock" Property="Visibility" Value="Visible"></Setter>
                                <Setter TargetName="MessageTextBlock" Property="Opacity" Value="0.5"></Setter>
                            </MultiTrigger>
                            <DataTrigger Binding="{Binding ElementName=CheckedToggleButton, Path=IsChecked}" Value="True">
                                <Setter TargetName="PasswordTextBox" Property="Visibility" Value="Visible"></Setter>
                                <Setter TargetName="PART_ContentHost" Property="Visibility" Value="Hidden"></Setter>
                            </DataTrigger>
                        </ControlTemplate.Triggers> 
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <StackPanel Margin="20">
        <PasswordBox Height="60" 
                     Tag="请输入密码"
                     x:Name="LoginPasswordBox"
                     PasswordChanged="LoginPasswordBox_OnPasswordChanged"></PasswordBox>
    </StackPanel>
  private void LoginPasswordBox_OnPasswordChanged(object sender, RoutedEventArgs e)
  {
      if (sender is System.Windows.Controls.PasswordBox pb)
      {
           PasswordBoxAttached.SetPassword(pb, pb.Password);
      }
  }

标签:SecureString,控件,string,PasswordBox,System,pb,WPF,Password
来源: https://www.cnblogs.com/dongweian/p/16414666.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有