[英]How to make TextBox to use password characters instead of using passwordbox in 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.