WPF PasswordBox MVVM implementation, wpfpasswordbox
Because the PasswordBox. Password attribute is not dependent, it cannot be used as the binding target. The following is my MVVM implementation method.
PasswordBox. Password is synchronized with TextBox. Text. TextBox is used only for demonstration. The Source bound to TextBox. Text is used.
Use Behavior to add the event processor of the PasswordChanged event and customize an additional property to bind the event. Behavior must reference System. Windows. Interactivity. dll. The Code is as follows:
using System.Windows;using System.Windows.Controls;using System.Windows.Interactivity;namespace PasswordHelperTest{ public static class PasswordBoxHelper { public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordBoxHelper), new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged)); private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; string password = (string)e.NewValue; if (passwordBox != null && passwordBox.Password != password) { passwordBox.Password = password; } } public static string GetPassword(DependencyObject dp) { return (string)dp.GetValue(PasswordProperty); } public static void SetPassword(DependencyObject dp, string value) { dp.SetValue(PasswordProperty, value); } } public class PasswordBoxBehavior : Behavior<PasswordBox> { protected override void OnAttached() { base.OnAttached(); AssociatedObject.PasswordChanged += OnPasswordChanged; } private static void OnPasswordChanged(object sender, RoutedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; string password = PasswordBoxHelper.GetPassword(passwordBox); if (passwordBox != null && passwordBox.Password != password) { PasswordBoxHelper.SetPassword(passwordBox, passwordBox.Password); } } protected override void OnDetaching() { base.OnDetaching(); AssociatedObject.PasswordChanged -= OnPasswordChanged; } }}
The View code is as follows:
<Window x:Class="PasswordHelperTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:local="clr-namespace:PasswordHelperTest" Title="MainWindow" Height="350" Width="525"> <StackPanel> <PasswordBox Margin="3" local:PasswordBoxHelper.Password="{Binding Path=Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <i:Interaction.Behaviors> <local:PasswordBoxBehavior /> </i:Interaction.Behaviors> </PasswordBox> <TextBox Margin="3" Text="{Binding Path=Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox> </StackPanel></Window>
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 PasswordHelperTest {/// <summary> /// MainWindow. interaction logic of xaml // </summary> public partial class MainWindow: Window {public MainWindow () {InitializeComponent (); this. dataContext = new MainWindowViewModel ();}}}
ViewModel references Microsoft. Practices. Prism. dll. The Code is as follows:
using Microsoft.Practices.Prism.ViewModel;using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace PasswordHelperTest{ class MainWindowViewModel : NotificationObject { private string _password; public string Password { get { return _password; } set { if (_password != value) { _password = value; this.RaisePropertyChanged("Password"); } } } }}