diff --git a/RMWPFUserInterface/BootStrapper.cs b/RMWPFUserInterface/BootStrapper.cs index 6301610..cb3497f 100644 --- a/RMWPFUserInterface/BootStrapper.cs +++ b/RMWPFUserInterface/BootStrapper.cs @@ -1,4 +1,5 @@ using Caliburn.Micro; +using RMWPFUserInterface.Helpers; using RMWPFUserInterface.ViewModels; using System; using System.Collections.Generic; @@ -6,6 +7,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; +using System.Windows.Controls; namespace RMWPFUserInterface { @@ -15,6 +17,11 @@ namespace RMWPFUserInterface public BootStrapper() { Initialize(); + + ConventionManager.AddElementConvention( + PasswordBoxHelper.BoundPasswordProperty, + "Password", + "PasswordChanged"); } protected override void Configure() { diff --git a/RMWPFUserInterface/Helpers/PasswordBoxHelper.cs b/RMWPFUserInterface/Helpers/PasswordBoxHelper.cs new file mode 100644 index 0000000..8c1d50d --- /dev/null +++ b/RMWPFUserInterface/Helpers/PasswordBoxHelper.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace RMWPFUserInterface.Helpers +{ + 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 }); + + } + } +} diff --git a/RMWPFUserInterface/RMWPFUserInterface.csproj b/RMWPFUserInterface/RMWPFUserInterface.csproj index 7331121..29f8aab 100644 --- a/RMWPFUserInterface/RMWPFUserInterface.csproj +++ b/RMWPFUserInterface/RMWPFUserInterface.csproj @@ -74,7 +74,12 @@ Designer + + + + LoginView.xaml + ShellView.xaml @@ -82,6 +87,10 @@ App.xaml Code + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/RMWPFUserInterface/ViewModels/LoginViewModel.cs b/RMWPFUserInterface/ViewModels/LoginViewModel.cs new file mode 100644 index 0000000..d546fa4 --- /dev/null +++ b/RMWPFUserInterface/ViewModels/LoginViewModel.cs @@ -0,0 +1,57 @@ +using Caliburn.Micro; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RMWPFUserInterface.ViewModels +{ + public class LoginViewModel : Screen + { + private string _userName; + private string _password; + public string UserName + { + get { return _userName; } + set + { + _userName = value; + NotifyOfPropertyChange(() => UserName); + NotifyOfPropertyChange(() => CanLogIn); + } + } + + public string Password + { + get { return _password; } + set + { + _password = value; + NotifyOfPropertyChange(() => Password); + NotifyOfPropertyChange(() => CanLogIn); + } + } + + public bool CanLogIn + { + get{ + + bool output = false; + + if (UserName?.Length > 0 && Password?.Length > 0) + { + output = true; + } + + return output; + + } + } + + public void LogIn() + { + Console.WriteLine(); + } + } +} diff --git a/RMWPFUserInterface/ViewModels/ShellViewModel.cs b/RMWPFUserInterface/ViewModels/ShellViewModel.cs index 4a302d8..a7c41a3 100644 --- a/RMWPFUserInterface/ViewModels/ShellViewModel.cs +++ b/RMWPFUserInterface/ViewModels/ShellViewModel.cs @@ -3,10 +3,17 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Caliburn.Micro; namespace RMWPFUserInterface.ViewModels { - public class ShellViewModel + public class ShellViewModel : Conductor { + private LoginViewModel _loginVM; + public ShellViewModel(LoginViewModel loginVM) + { + _loginVM = loginVM; + ActivateItemAsync(_loginVM); + } } } diff --git a/RMWPFUserInterface/Views/LoginView.xaml b/RMWPFUserInterface/Views/LoginView.xaml new file mode 100644 index 0000000..ecdb6ea --- /dev/null +++ b/RMWPFUserInterface/Views/LoginView.xaml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + Login Form + + + + + Username: + + + + + + Password: + + + + + + + diff --git a/RMWPFUserInterface/Views/LoginView.xaml.cs b/RMWPFUserInterface/Views/LoginView.xaml.cs new file mode 100644 index 0000000..5a1e97e --- /dev/null +++ b/RMWPFUserInterface/Views/LoginView.xaml.cs @@ -0,0 +1,28 @@ +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 RMWPFUserInterface.Views +{ + /// + /// Interaction logic for LoginView.xaml + /// + public partial class LoginView : UserControl + { + public LoginView() + { + InitializeComponent(); + } + } +} diff --git a/RMWPFUserInterface/Views/ShellView.xaml b/RMWPFUserInterface/Views/ShellView.xaml index 9087023..cbd799f 100644 --- a/RMWPFUserInterface/Views/ShellView.xaml +++ b/RMWPFUserInterface/Views/ShellView.xaml @@ -6,7 +6,17 @@ xmlns:local="clr-namespace:RMWPFUserInterface.Views" mc:Ignorable="d" Title="ShellView" Height="450" Width="800"> - - - + + + + + + + + + + + + +