Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caliburn.Micro support for PasswordBox?

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 from that example. Don't see how this would work anyway since the names are not the same case. Does anyone have a CM example that does allow me to get the value of the PasswordBox? Is there a particular version of CM required? I'm running version 1.5.2 of CM. Ideally w/o using Attached Properties but if can work with CM and the only way then fine. Please no lectures on security issues as that is not an issue in my case.


Apply methods between your view and view model automatically with parameters and guard methods

<StackPanel>     <TextBox x:Name="Username" />     <PasswordBox x:Name="Password" />     <Button x:Name="Login" Content="Log in" /> </StackPanel> 

public bool CanLogin(string username, string password) {     return !String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password); }  public string Login(string username, string password) {     ... } 
like image 565
Dave Avatar asked Jun 03 '15 21:06

Dave


People also ask

Does Caliburn Micro support for Passwordbox?

We can very easily use Caliburn. Micro actions to send our password to the ViewModel. Then remember to clear the password fields so they don't remain in memory.

Why use Caliburn micro?

A small, yet powerful framework, designed for building applications across all XAML platforms (. NET 4.5+ and . NET Core 3.0+). Its strong support for MV* patterns will enable you to build your solution quickly, without the need to sacrifice code quality or testability.


1 Answers

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<PasswordBox>(             PasswordBoxHelper.BoundPasswordProperty,             "Password",             "PasswordChanged");     }      // other bootstrapper stuff here } 
like image 171
FMM Avatar answered Sep 28 '22 06:09

FMM