zoukankan      html  css  js  c++  java
  • WPF MVVM从入门到精通5:PasswordBox的绑定

    读到这里,可能有的读者会发现,我们只讲了用户名的绑定,然后就说到登录事件了,跳过了密码框和单选框的绑定。是因为这两者完全类似,不需要讲吗?并不是,而是因为它们涉及到了新的课题。

    对于PasswordBox,可能很多人都会按着TextBox的路子,在ViewModel里面写一个属性,然后绑定到Password属性上。当你写完这一切的时候,你会突然收到Visual Studio的提示:Password并不是依赖属性,不能绑定!

    当然,微软的工程师们这样设计是有原因的,毕竟绑定可能引起密码的泄漏问题。

    那我们要怎么办呢?路子有两条:

    (1)改造TextBox,把显示的字符改成***这种。

    (2)改造PasswordBox,增加一个依赖属性,借助它读和写Password属性。

    可能第二条路子会简单一些,我们选择这条路子。先上代码:

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Interactivity;
    
    namespace LoginDemo.ViewModel.Common
    {
        /// <summary>
        /// 增加Password扩展属性
        /// </summary>
        public static class PasswordBoxHelper
        {
            public static string GetPassword(DependencyObject obj)
            {
                return (string)obj.GetValue(PasswordProperty);
            }
    
            public static void SetPassword(DependencyObject obj, string value)
            {
                obj.SetValue(PasswordProperty, value);
            }
    
            public static readonly DependencyProperty PasswordProperty =
                DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordBoxHelper), new PropertyMetadata("", OnPasswordPropertyChanged));
    
            private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
            {
                PasswordBox box = sender as PasswordBox;
                string password = (string)e.NewValue;
                if (box != null && box.Password != password)
                {
                    box.Password = password;
                }
            }
        }
    
        /// <summary>
        /// 接收PasswordBox的密码修改事件
        /// </summary>
        public class PasswordBoxBehavior : Behavior<PasswordBox>
        {
            protected override void OnAttached()
            {
                base.OnAttached();
    
                AssociatedObject.PasswordChanged += OnPasswordChanged;
            }
    
            protected override void OnDetaching()
            {
                base.OnDetaching();
    
                AssociatedObject.PasswordChanged -= OnPasswordChanged;
            }
    
            private static void OnPasswordChanged(object sender, RoutedEventArgs e)
            {
                PasswordBox box = sender as PasswordBox;
                string password = PasswordBoxHelper.GetPassword(box);
                if (box != null && box.Password != password)
                {
                    PasswordBoxHelper.SetPassword(box, box.Password);
                }
            }
        }
    }
    

    我们为PasswordBox增加一个扩展属性,修改这个属性,就会修改密码。但反过来,当密码框的内容改变时,附加属性是收不到消息的。这时我们需要PasswordBoxBehavior这个行为。密码框内容改变,就会通知它,然后附加属性相应地改变自己的值。

    我们把XAML文件密码框的代码改成如下所示:

    <PasswordBox Grid.Row="1" Grid.Column="1" Margin="5" c:PasswordBoxHelper.Password="{Binding Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
        <i:Interaction.Behaviors>
            <c:PasswordBoxBehavior/>
        </i:Interaction.Behaviors>
    </PasswordBox>
    

    在ViewModel文件里面,增加对密码的定义:

    /// <summary>
    /// 密码
    /// </summary>
    public string Password
    {
        get
        {
            return obj.Password;
        }
        set
        {
            obj.Password = value;
            this.RaisePropertyChanged("Password");
        }
    }

    至此,密码框的绑定就完成了。

  • 相关阅读:
    在jenkins和sonar中集成jacoco(一)--使用jacoco收集单元测试的覆盖率
    持续集成一天一美元
    在jenkins和sonar中集成jacoco(二)--在jenkins中生成jacoco覆盖率报告
    day02--课后练习
    python之路-day02
    day01--课后练习
    python之路-day01
    python-FTP程序
    python-选课系统
    python- ATM与购物商城
  • 原文地址:https://www.cnblogs.com/ljdong7/p/12054647.html
Copyright © 2011-2022 走看看