How to bind to a PasswordBox in MVVM

前端 未结 30 2215
执念已碎
执念已碎 2020-11-22 11:50

I have come across a problem with binding to a PasswordBox. It seems it\'s a security risk but I am using the MVVM pattern so I wish to bypass this. I found som

30条回答
  •  借酒劲吻你
    2020-11-22 12:42

    To me, both of these things feel wrong:

    • Implementing clear text password properties
    • Sending the PasswordBox as a command parameter to the ViewModel

    Transferring the SecurePassword (SecureString instance) as described by Steve in CO seems acceptable. I prefer Behaviors to code behind, and I also had the additional requirement of being able to reset the password from the viewmodel.

    Xaml (Password is the ViewModel property):

    
        
            
        
    
    

    Behavior:

    using System.Security;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Interactivity;
    
    namespace Evidence.OutlookIntegration.AddinLogic.Behaviors
    {
        /// 
        /// Intermediate class that handles password box binding (which is not possible directly).
        /// 
        public class PasswordBoxBindingBehavior : Behavior
        {
            // BoundPassword
            public SecureString BoundPassword { get { return (SecureString)GetValue(BoundPasswordProperty); } set { SetValue(BoundPasswordProperty, value); } }
            public static readonly DependencyProperty BoundPasswordProperty = DependencyProperty.Register("BoundPassword", typeof(SecureString), typeof(PasswordBoxBindingBehavior), new FrameworkPropertyMetadata(OnBoundPasswordChanged));
    
            protected override void OnAttached()
            {
                this.AssociatedObject.PasswordChanged += AssociatedObjectOnPasswordChanged;
                base.OnAttached();
            }
    
            /// 
            /// Link up the intermediate SecureString (BoundPassword) to the UI instance
            /// 
            private void AssociatedObjectOnPasswordChanged(object s, RoutedEventArgs e)
            {
                this.BoundPassword = this.AssociatedObject.SecurePassword;
            }
    
            /// 
            /// Reacts to password reset on viewmodel (ViewModel.Password = new SecureString())
            /// 
            private static void OnBoundPasswordChanged(object s, DependencyPropertyChangedEventArgs e)
            {
                var box = ((PasswordBoxBindingBehavior)s).AssociatedObject;
                if (box != null)
                {
                    if (((SecureString)e.NewValue).Length == 0)
                        box.Password = string.Empty;
                }
            }
    
        }
    }
    

提交回复
热议问题