你的位置:首页 > ASP.net教程

[ASP.net教程]WPF PasswordBox MVVM 实现


由于PasswordBox.Password属性非依赖属性,所以不能作为绑定的目标,以下是本人的MVVM实现方法。

 

通过Behavior添加PasswordChanged事件的事件处理器,以及自定义一个附加属性实现绑定,Behavior需要引用System.Windows.Interactivity.dll,代码如下:

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;    }  }}

View代码如下:

<Window x:Class="PasswordHelperTest.MainWindow"    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    ="http://schemas.microsoft.com/winfx/2006/xaml"    ="http://schemas.microsoft.com/expression/2010/interactivity"    ="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.xaml 的交互逻辑  /// </summary>  public partial class MainWindow : Window  {    public MainWindow()    {      InitializeComponent();      this.DataContext = new MainWindowViewModel();    }  }}

ViewModel引用Microsoft.Practices.Prism.dll,代码如下:

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");        }      }    }  }}