Следующее решение использует TextBox
для отображения пароля в виде обычного текста и PasswordBox
для маскирования пароля. PasswordBox
находится поверх TextBox
, поэтому сначала вы увидите замаскированный пароль. Когда флажок «показать пароль» установлен, PasswordBox
скрыт, что показывает TextBox
внизу (и пароль в текстовом виде). Вот XAML:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="VisibilityConverter" />
</Window.Resources>
<StackPanel>
<Grid>
<TextBox
Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}"
/>
<PasswordBox
x:Name="PasswordBox"
PasswordChanged="OnPasswordChanged"
Visibility="{Binding HidePassword, Converter={StaticResource VisibilityConverter}}"
/>
</Grid>
<CheckBox
Content="Show password"
IsChecked="{Binding ShowPassword}"
/>
</StackPanel>
Он не использует MVVM для всего (обратите внимание на обработчик событий OnPasswordChanged
). Это потому, что PasswordBox
не может использовать привязку, поэтому пароль должен быть установлен в коде позади. Но прежде чем показать это, вот модель представления:
public class ViewModel : ViewModelBase
{
private string _password;
public string Password
{
get => _password;
set => Set(ref _password, value);
}
private bool _showPassword;
public bool ShowPassword
{
get => _showPassword;
set
{
Set(ref _showPassword, value);
RaisePropertyChanged(nameof(HidePassword));
}
}
public bool HidePassword => !ShowPassword;
}
Методы Set
происходят из родительского класса ViewModelBase
, который является частью MVVM Light Toolkit. Метод Set
просто устанавливает поле поддержки свойства и вызывает событие PropertyChanged
для этого свойства.
Наконец, вот код:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitializeViewModel();
}
public ViewModel ViewModel => DataContext as ViewModel;
private void InitializeViewModel()
{
DataContext = new ViewModel();
ViewModel.PropertyChanged += (sender, args) =>
{
// Update the password box only when it's not visible;
// otherwise, the cursor goes to the beginning on each keystroke
if (!PasswordBox.IsVisible)
{
if (args.PropertyName == nameof(ViewModel.Password))
PasswordBox.Password = ViewModel.Password;
}
};
}
private void OnPasswordChanged(object sender, RoutedEventArgs e)
{
ViewModel.Password = PasswordBox.Password;
}
}
После установки DataContext
в новое ViewModel
мы прослушиваем изменения свойства Password
, чтобы обновить его в PasswordBox
. Обратите внимание, что мы делаем это только тогда, когда PasswordBox
не виден (в противном случае курсор устанавливается на начало при каждом нажатии клавиши, и в итоге мы переворачиваем пароль!)
Обработчик событий просто обновляет Password
в модели представления при каждом изменении в PasswordBox
.
Код для «подтверждения пароля» TextBox
и PasswordBox
будет очень похож.