Caliburn.Micro support for PasswordBox?

前端 未结 3 464
遇见更好的自我
遇见更好的自我 2020-12-25 13:03

The Caliburn.Micro home page at http://caliburnmicro.com makes the below claim but I am unable to make CM work with a PasswordBox control using any variation I can think of

3条回答
  •  南方客
    南方客 (楼主)
    2020-12-25 13:25

    Here's a much more simplified example, including a binding convention so that PasswordBox binding in Caliburn.Micro Just Works™:

    public static class PasswordBoxHelper
    {
        public static readonly DependencyProperty BoundPasswordProperty =
            DependencyProperty.RegisterAttached("BoundPassword",
                typeof(string),
                typeof(PasswordBoxHelper),
                new FrameworkPropertyMetadata(string.Empty, OnBoundPasswordChanged));
    
        public static string GetBoundPassword(DependencyObject d)
        {
            var box = d as PasswordBox;
            if (box != null)
            {
                // this funny little dance here ensures that we've hooked the
                // PasswordChanged event once, and only once.
                box.PasswordChanged -= PasswordChanged;
                box.PasswordChanged += PasswordChanged;
            }
    
            return (string)d.GetValue(BoundPasswordProperty);
        }
    
        public static void SetBoundPassword(DependencyObject d, string value)
        {
            if (string.Equals(value, GetBoundPassword(d)))
                return; // and this is how we prevent infinite recursion
    
            d.SetValue(BoundPasswordProperty, value);
        }
    
        private static void OnBoundPasswordChanged(
            DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            var box = d as PasswordBox;
    
            if (box == null)
                return;
    
            box.Password = GetBoundPassword(d);
        }
    
        private static void PasswordChanged(object sender, RoutedEventArgs e)
        {
            PasswordBox password = sender as PasswordBox;
    
            SetBoundPassword(password, password.Password);
    
            // set cursor past the last character in the password box
            password.GetType().GetMethod("Select", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(password, new object[] { password.Password.Length, 0 }); 
        }
    
    }
    

    Then, in your bootstrapper:

    public sealed class Bootstrapper : BootstrapperBase
    {
        public Bootstrapper()
        {
            Initialize();
    
            ConventionManager.AddElementConvention(
                PasswordBoxHelper.BoundPasswordProperty,
                "Password",
                "PasswordChanged");
        }
    
        // other bootstrapper stuff here
    }
    

提交回复
热议问题