簡體   English   中英

使用文本框作為密碼框,並在 wpf 中設置密碼字符

[英]Using a textbox as a passwordbox with a password char set in wpf

我在嘗試使用密碼字符和占位符設置文本框時遇到問題。 我已經為用戶名做了一個,效果很好,但我對密碼框能做什么感到困惑。

我知道你可以有一個帶有密碼字符的密碼框,但你不能在 wpf 中也有一個占位符。

我有這個用戶名,我想對密碼框做同樣的事情:

this.usernameTxt.Foreground = Brushes.LightGray;

        this.usernameTxt.Text = "Username";

this.usernameTxt.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(this.usernameTxt_Selected);

this.usernameTxt.PreviewLostKeyboardFocus += new KeyboardFocusChangedEventHandler(this.usernameTxt_Lostfocus);

public void usernameTxt_Lostfocus(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(usernameTxt.Text))
                    {
                        this.usernameTxt.Text = "Username";
                        this.usernameTxt.Foreground = Brushes.LightGray;
                    }
    }

    public void usernameTxt_Selected(object sender, EventArgs e)
    {
            this.usernameTxt.Focus();
            this.usernameTxt.SelectAll();
            this.usernameTxt.Text = "";
            this.usernameTxt.Foreground = Brushes.Black;
    }

您可以查看以下變通辦法。 在此示例中,我依靠嵌入在密碼控件中的文本框控件的TextChanged事件。

觸發TextChanged事件時,我使用堆棧來捕獲最后輸入的字符,然后在視圖模型中維護一個混淆的密碼以及一個實際的密碼。 當按下刪除或返回鍵時,我彈出從堆棧中輸入的最后一個字符。

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:converters="clr-namespace:WpfApplication1.Converters"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <PasswordBox x:Name="passwordBox" Height="20" PasswordChar="*" Width="200" Background="LightYellow" >
            <PasswordBox.Template>
                <ControlTemplate>
                    <TextBox x:Name="PasswordTextbox" GotFocus="GotFocus" Text="{Binding ObfuscatedPassword, Mode=TwoWay}" KeyUp="PasswordTextbox_KeyUp" TextAlignment="Center" Foreground="LightGray" />
                </ControlTemplate>
            </PasswordBox.Template>
        </PasswordBox>
    </Grid>
</Window>

視圖模型:

namespace WpfApplication1
{
    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string obfuscatedPassword = "user name";

        public string ObfuscatedPassword
        {
            get { return obfuscatedPassword; }
            set 
            { 
                if (this.obfuscatedPassword != value)
                {
                    this.obfuscatedPassword = value;
                    OnPropertyChanged();
                }
            }
        }

        private string actualPassword = null;
        public string ActualPassword
        {
            get { return actualPassword; }
            set
            {
                if (this.actualPassword != value)
                {
                    this.actualPassword = value;
                    OnPropertyChanged();
                }
            }
        }

        private void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

后台代碼:

public partial class MainWindow : Window
{
    ViewModel viewModel = null;
    public MainWindow()
    {
        InitializeComponent();

        this.viewModel = this.DataContext as ViewModel;
    }

    public string defaultText = "user name";

    Stack<string> charStack = new Stack<string>();


    private void PasswordTextbox_KeyUp(object sender, KeyEventArgs e)
    {
        var textbox = sender as TextBox;
        textbox.Text = string.Empty;

        var key = e.Key.ToString();

        if (this.viewModel.ObfuscatedPassword == defaultText)
        {
            this.viewModel.ObfuscatedPassword = string.Empty;
        }

        var deleteLastCharacter = (e.Key == Key.Delete || e.Key == Key.Back);

        if (deleteLastCharacter)
        {

            if (charStack.Count > 0)
            {
                charStack.Pop();
            }

            if (charStack.Count == 0)
            {
                textbox.Text = defaultText;
                textbox.CaretIndex = defaultText.Length;
                textbox.SelectAll();
                e.Handled = true;
                return;
            }
        }
        else if (IsTextAllowed(key))
        {
            charStack.Push(key);
        }
        else
        {
            e.Handled = true;
            return;
        }

        this.viewModel.ObfuscatedPassword = ObfuscatePassword();
        this.viewModel.ActualPassword = ActualizePassword();

        textbox.CaretIndex = this.viewModel.ObfuscatedPassword.Length;
        e.Handled = true;
    }

    private static bool IsTextAllowed(string text)
    {
        Regex regex = new Regex(@"^.*(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$"); //regex that matches disallowed text
        return !regex.IsMatch(text);
    }

    private string ActualizePassword()
    {
        var password = string.Empty;

        foreach (var character in charStack.Reverse())
        {
            password += character;
        }

        return password;
    }

    private string ObfuscatePassword()
    {
        var password = string.Empty;

        foreach (var character in charStack.Reverse())
        {
            password += passwordBox.PasswordChar;
        }

        return password;
    }

    private void GotFocus(object sender, RoutedEventArgs e)
    {
        if (this.viewModel.ObfuscatedPassword == defaultText)
        {
            this.viewModel.ObfuscatedPassword = string.Empty;
        }
    }

}

首先從這個鏈接下載密碼點字體, https://github.com/davidagraf/passwd/blob/master/public/ttf/password.ttf

在此 put password.ttf 文件下添加名為“AppFonts”的文件夾,並將此字體的引用添加到您的 WPF 應用程序 App.xaml。 因此,您可以在全球范圍內訪問此字體。

<Application.Resources>
        <ResourceDictionary>            
            <Style x:Key="CustomFont">                
                <Setter Property="TextElement.FontFamily" Value="/AppFonts/#password"></Setter>
            </Style>
        </ResourceDictionary>
    </Application.Resources>

創建 PasswordViewModel 並下載 GalaSoft 的 nuget 包 MvvmLight。

using System;
using GalaSoft.MvvmLight;

public class PasswordViewModel : ViewModelBase
    {
     private string _PlainPassword { get; set; }
     public string PlainPassword
        {
            get { 
               
                return _PlainPassword; 
            }
            set
            {
                _PlainPassword = value;
                RaisePropertyChanged("Password");
            }
        }
}

現在創建您的視圖 PasswordUserControl.xaml 並將視圖構造函數添加到 DataContext。

  PasswordViewModel passwordModel= new PasswordViewModel();
  this.DataContext = passwordModel;

並在查看 xaml 粘貼此

<Grid  Margin="20,0,15,0" Height="45">
              
                <TextBox Grid.Row="3" Name="txtPasswordEntry" Background="Transparent" Padding="12" Foreground="#787878" Height="45" 
                Text="{Binding PlainPassword,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" 
                FontFamily="/WpfApplication;component/AppFonts/#Password" FontSize="14" FontWeight="Medium">
                    <TextBox.InputBindings>
                        <!--Disable CTRL+C (COPY) -->
                        <KeyBinding Command="ApplicationCommands.NotACommand" Key="C" Modifiers="Control" />
                        <!--Disable CTRL+X (CUT) -->
                        <KeyBinding Command="ApplicationCommands.NotACommand" Key="X" Modifiers="Control" />
                    </TextBox.InputBindings>
                    <TextBox.ContextMenu>
                        <!--Hide context menu where you could copy/cut as well -->
                        <ContextMenu Visibility="Collapsed" />
                    </TextBox.ContextMenu>
                </TextBox>
                <TextBlock IsHitTestVisible="False" Padding="13" Text="Password" Foreground="#787878" Height="45" FontSize="14" FontWeight="Medium">
                <TextBlock.Style>
                    <Style TargetType="{x:Type TextBlock}">
                        <Setter Property="Visibility" Value="Collapsed"/>
                        <Style.Triggers>
                                <DataTrigger Binding="{Binding Text, ElementName=txtPasswordEntry}" Value="">
                                <Setter Property="Visibility" Value="Visible"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
            </Grid>

注意:聽到 FontFamily="/WpfApplication;component/AppFonts/#Password" WpfApplication 是您的應用程序名稱。 或者您可以從文本框屬性更改字體系列。

現在運行應用程序。 請參閱密碼框有一個占位符文本密碼並輸入您的密碼它將消失。 而且它是安全的,你不能復制這個密碼。 在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM