Created shell and login WPF forms

This commit is contained in:
s459315 2022-07-08 16:27:24 +02:00
parent f582cf6653
commit ad7cb45908
8 changed files with 235 additions and 4 deletions

View File

@ -1,4 +1,5 @@
using Caliburn.Micro; using Caliburn.Micro;
using RMWPFUserInterface.Helpers;
using RMWPFUserInterface.ViewModels; using RMWPFUserInterface.ViewModels;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -6,6 +7,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls;
namespace RMWPFUserInterface namespace RMWPFUserInterface
{ {
@ -15,6 +17,11 @@ namespace RMWPFUserInterface
public BootStrapper() public BootStrapper()
{ {
Initialize(); Initialize();
ConventionManager.AddElementConvention<PasswordBox>(
PasswordBoxHelper.BoundPasswordProperty,
"Password",
"PasswordChanged");
} }
protected override void Configure() protected override void Configure()
{ {

View File

@ -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 });
}
}
}

View File

@ -74,7 +74,12 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="BootStrapper.cs" /> <Compile Include="BootStrapper.cs" />
<Compile Include="Helpers\PasswordBoxHelper.cs" />
<Compile Include="ViewModels\LoginViewModel.cs" />
<Compile Include="ViewModels\ShellViewModel.cs" /> <Compile Include="ViewModels\ShellViewModel.cs" />
<Compile Include="Views\LoginView.xaml.cs">
<DependentUpon>LoginView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ShellView.xaml.cs"> <Compile Include="Views\ShellView.xaml.cs">
<DependentUpon>ShellView.xaml</DependentUpon> <DependentUpon>ShellView.xaml</DependentUpon>
</Compile> </Compile>
@ -82,6 +87,10 @@
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Page Include="Views\LoginView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ShellView.xaml"> <Page Include="Views\ShellView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@ -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();
}
}
}

View File

@ -3,10 +3,17 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Caliburn.Micro;
namespace RMWPFUserInterface.ViewModels namespace RMWPFUserInterface.ViewModels
{ {
public class ShellViewModel public class ShellViewModel : Conductor<Object>
{ {
private LoginViewModel _loginVM;
public ShellViewModel(LoginViewModel loginVM)
{
_loginVM = loginVM;
ActivateItemAsync(_loginVM);
}
} }
} }

View File

@ -0,0 +1,46 @@
<UserControl x:Class="RMWPFUserInterface.Views.LoginView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:RMWPFUserInterface.Views"
mc:Ignorable="d" Background="White" FontSize="24"
d:DesignHeight="425" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Margin="0 0 0 20"
HorizontalAlignment="Center" FontSize="64" FontFamily="Segoe UI Light">
Login Form
</TextBlock>
<!-- Username row -->
<TextBlock Grid.Row="1" Grid.Column="1" Margin="0 0 10 20">
Username:
</TextBlock>
<TextBox x:Name="UserName" Grid.Row="1" Grid.Column="2" MinWidth="200" Margin="0 0 0 10"/>
<!-- Password row -->
<TextBlock Grid.Row="2" Grid.Column="1" Margin="0 0 10 20">
Password:
</TextBlock>
<PasswordBox x:Name="Password" Grid.Row="2" Grid.Column="2" MinWidth="200" Margin="0 0 0 10"/>
<!-- Login button -->
<Button Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Padding="20 5"
HorizontalAlignment="Center" x:Name="LogIn">
Log in
</Button>
</Grid>
</UserControl>

View File

@ -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
{
/// <summary>
/// Interaction logic for LoginView.xaml
/// </summary>
public partial class LoginView : UserControl
{
public LoginView()
{
InitializeComponent();
}
}
}

View File

@ -6,7 +6,17 @@
xmlns:local="clr-namespace:RMWPFUserInterface.Views" xmlns:local="clr-namespace:RMWPFUserInterface.Views"
mc:Ignorable="d" mc:Ignorable="d"
Title="ShellView" Height="450" Width="800"> Title="ShellView" Height="450" Width="800">
<Grid> <DockPanel>
<Menu DockPanel.Dock="Top" FontSize="18">
<MenuItem Header="_File">
</MenuItem>
<MenuItem Header="_Account">
<MenuItem x:Name="LoginScreen" Header="_Login" />
</MenuItem>
</Menu>
<Grid>
<ContentControl x:Name="ActiveItem" Margin="5" />
</Grid> </Grid>
</DockPanel>
</Window> </Window>