• 00
  • :
  • 00
  • :
  • 00

WPF PasswordBox MVVM 实现

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

 

PasswordBox.Password与TextBox.Text同步,TextBox只是为了演示,实际使用的是TextBox.Text绑定的Source。

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

            }
        }

    }
}
复制代码

 

posted @ 2020-02-03 19:58  Garson_Zhang  阅读(497)  评论(0编辑  收藏  举报