Better Entry URL go to button

Migrated code from code behind pages to view models
Auto select Recents if there are any recent items
WIP auto focus on password box when opening database
This commit is contained in:
2017-10-09 18:40:02 +02:00
committed by BONNEVILLE Geoffroy
parent f2794f8055
commit 98ecb0b8a1
15 changed files with 134 additions and 71 deletions

View File

@@ -7,14 +7,14 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="65"
d:DesignWidth="400">
d:DesignWidth="335" Loaded="UserControl_Loaded">
<StackPanel>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal" Margin="0,-1,0,-1" >
<PasswordBox x:Name="PasswordBox" Width="300" IsPasswordRevealButtonEnabled="True" KeyDown="PasswordBox_KeyDown" PlaceholderText="Password"/>
<Button Click="OpenButton_OnClick" Width="auto">
<Button Click="OpenButton_OnClick" Width="auto" Padding="2,0">
<SymbolIcon Symbol="Forward" />
</Button>
</StackPanel>
<TextBlock x:Name="StatusTextBlock" Height="auto" Width="auto" Foreground="#FF9E1B1B" FontSize="16" />
<TextBlock x:Name="StatusTextBlock" Height="32" Width="auto" Foreground="#FFBF6969" FontSize="16" FontWeight="Bold" />
</StackPanel>
</UserControl>

View File

@@ -1,5 +1,7 @@
using System;
using System.Threading.Tasks;
using Windows.System;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
@@ -13,11 +15,10 @@ namespace ModernKeePass.Controls
public OpenDatabaseUserControl()
{
InitializeComponent();
PasswordBox.Focus(FocusState.Programmatic);
}
public delegate void PasswordCheckedEventHandler(object sender, EventArgs e);
public event PasswordCheckedEventHandler ValidationChecked;
public delegate void PasswordCheckedEventHandler(object sender, EventArgs e);
private void OpenButton_OnClick(object sender, RoutedEventArgs e)
{
@@ -30,5 +31,12 @@ namespace ModernKeePass.Controls
{
if (e.Key == VirtualKey.Enter) OpenButton_OnClick(null, null);
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(
() => Dispatcher.RunAsync(CoreDispatcherPriority.Low,
() => PasswordBox.Focus(FocusState.Programmatic)));
}
}
}

View File

@@ -30,6 +30,7 @@
SelectionChanged="ListView_SelectionChanged"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
ItemsSource="{Binding Source={StaticResource MenuItemsSource}}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="False">
<ListView.Header>
<TextBlock Text="ModernKeePass" FontWeight="Bold" FontSize="36" Margin="20" />

View File

@@ -1,10 +1,5 @@
using System.Collections.ObjectModel;
using System.Linq;
using Windows.Storage.AccessCache;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Pages;
using ModernKeePass.ViewModels;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
@@ -24,38 +19,13 @@ namespace ModernKeePass
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var mainMenuItems = new ObservableCollection<MainMenuItemVm>
{
new MainMenuItemVm {Title = "Open", PageType = typeof(OpenDatabasePage), Destination = MenuFrame, Parameter = Frame, SymbolIcon = Symbol.Page2},
new MainMenuItemVm {Title = "New" /*, PageType = typeof(NewDatabasePage)*/, Destination = MenuFrame, SymbolIcon = Symbol.Add},
new MainMenuItemVm {Title = "Save" , PageType = typeof(SaveDatabasePage), Destination = MenuFrame, Parameter = Frame, SymbolIcon = Symbol.Save},
new MainMenuItemVm {Title = "Recent" , PageType = typeof(RecentDatabasesPage), Destination = MenuFrame, Parameter = Frame, SymbolIcon = Symbol.Copy}
};
var app = (App)Application.Current;
if (app.Database != null && app.Database.IsOpen)
mainMenuItems.Add(new MainMenuItemVm
{
Title = app.Database.Name,
PageType = typeof(GroupDetailPage),
Destination = Frame,
Parameter = app.Database.RootGroup,
Group = 1,
SymbolIcon = Symbol.ProtectedDocument
});
var mainVm = DataContext as MainVm;
mainVm.MainMenuItems = from item in mainMenuItems group item by item.Group into grp orderby grp.Key select grp;
/*if (app.Database == null || !app.Database.IsOpen)
{
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
if (mru.Entries.Count > 0) MenuListView.SelectedIndex = 3;
}*/
//mainVm.NotifyPropertyChanged("MainMenuItems");
DataContext = new MainVm(Frame, MenuFrame);
}
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var mainMenuItem = e.AddedItems[0] as MainMenuItemVm;
mainMenuItem?.Destination.Navigate(mainMenuItem.PageType, mainMenuItem.Parameter);
var mainVm = DataContext as MainVm;
mainVm.SelectedItem?.Destination.Navigate(mainVm.SelectedItem.PageType, mainVm.SelectedItem.Parameter);
}
}
}

View File

@@ -200,6 +200,11 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Styles\TextBoxWithButtonStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
</ItemGroup>
<ItemGroup>
<Reference Include="BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">

View File

@@ -44,14 +44,12 @@
<TextBox x:Name="passwordTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Password, Mode=TwoWay}" Width="350" Height="32" Visibility="{Binding IsRevealPassword, Converter={StaticResource BooleanToVisibilityConverter}}" />
<CheckBox x:Name="checkBox" HorizontalAlignment="Left" Margin="-3,0,0,0" Content="Show password" IsChecked="{Binding IsRevealPassword, Mode=TwoWay}"/>
<TextBlock x:Name="urlTextBlock" TextWrapping="Wrap" Text="URL" FontSize="18"/>
<Border Width="350" HorizontalAlignment="Left" BorderBrush="{StaticResource TextBoxBorderThemeBrush}" BorderThickness="2">
<StackPanel Orientation="Horizontal">
<TextBox x:Name="urlTextBox" TextWrapping="Wrap" Text="{Binding Url, Mode=TwoWay}" BorderThickness="0" Height="32" Width="300" MaxLength="256" />
<Button Click="UrlButton_Click" Height="32" BorderThickness="0" Background="Transparent" Margin="0">
<StackPanel Orientation="Horizontal" Margin="0,-1,0,-1" Width="350" HorizontalAlignment="Left">
<TextBox x:Name="urlTextBox" TextWrapping="Wrap" Text="{Binding Url, Mode=TwoWay}" Height="32" Width="350" MaxLength="256" Padding="0,0,34,0" />
<Button Click="UrlButton_Click" Height="34" Margin="-34,0,0,0" Background="Transparent" Padding="2,0" >
<SymbolIcon Symbol="Forward" VerticalAlignment="Center" />
</Button>
</StackPanel>
</Border>
<TextBlock x:Name="notesTextBlock" TextWrapping="Wrap" Text="Notes" FontSize="18"/>
<TextBox x:Name="notesTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" />
</StackPanel>

View File

@@ -42,7 +42,7 @@
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Horizontal scrolling grid -->
<SemanticZoom Grid.Row="1" >
<SemanticZoom Grid.Row="1" ViewChangeStarted="SemanticZoom_ViewChangeStarted" >
<SemanticZoom.ZoomedInView>
<GridView
x:Name="GridView"
@@ -193,7 +193,7 @@
<GroupStyle HidesIfEmpty="True">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Background="LightGray" Margin="0">
<Grid Background="LightGray" Margin="0,0,10,0" HorizontalAlignment="Left">
<TextBlock Text="{Binding Key}" Foreground="Black" Margin="30" Style="{StaticResource HeaderTextBlockStyle}"/>
</Grid>
</DataTemplate>

View File

@@ -104,5 +104,13 @@ namespace ModernKeePass.Pages
group?.RemoveGroup();
if (Frame.CanGoBack) Frame.GoBack();
}
private void SemanticZoom_ViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e)
{
if (e.IsSourceZoomedInView == false)
{
e.DestinationItem.Item = e.SourceItem.Item;
}
}
}
}

View File

@@ -5,22 +5,19 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:ModernKeePass.ViewModels"
xmlns:local="using:ModernKeePass.Controls"
xmlns:Converters="using:ModernKeePass.Converters"
xmlns:converters="using:ModernKeePass.Converters"
x:Class="ModernKeePass.Pages.RecentDatabasesPage"
mc:Ignorable="d">
<Page.Resources>
<Converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<CollectionViewSource
x:Name="RecentItemsSource"
Source="{Binding RecentItems}" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<CollectionViewSource x:Name="RecentItemsSource" Source="{Binding RecentItems}" />
</Page.Resources>
<Page.DataContext>
<viewModels:RecentVm/>
</Page.DataContext>
<ListView
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
ItemsSource="{Binding Source={StaticResource RecentItemsSource}}"
x:Name="RecentListView"
SelectionChanged="RecentListView_SelectionChanged"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<ListView.ItemTemplate>

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.Storage.AccessCache;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
@@ -28,12 +28,6 @@ namespace ModernKeePass.Pages
{
base.OnNavigatedTo(e);
_mainFrame = e.Parameter as Frame;
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
var recentVm = DataContext as RecentVm;
if (recentVm == null) return;
recentVm.RecentItems = new ObservableCollection<RecentItemVm>(
from entry in mru.Entries
select new RecentItemVm {Name = entry.Metadata, Token = entry.Token});
}
private async void RecentListView_SelectionChanged(object sender, SelectionChangedEventArgs e)

View File

@@ -0,0 +1,7 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ModernKeePass.Styles">
</ResourceDictionary>

View File

@@ -1,12 +1,14 @@
using System;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
namespace ModernKeePass.ViewModels
{
public class MainMenuItemVm: IIsEnabled
public class MainMenuItemVm: NotifyPropertyChangedBase, IIsEnabled
{
private string _title;
private bool _isSelected;
public string Title
{
@@ -21,6 +23,12 @@ namespace ModernKeePass.ViewModels
public Symbol SymbolIcon { get; set; }
public bool IsEnabled => PageType != null;
public bool IsSelected
{
get { return _isSelected; }
set { SetProperty(ref _isSelected, value); }
}
public override string ToString()
{
return Title;

View File

@@ -1,6 +1,4 @@
using System.ComponentModel;
using Windows.UI.Xaml;
using ModernKeePass.Common;
using ModernKeePass.Common;
namespace ModernKeePass.ViewModels
{

View File

@@ -1,16 +1,73 @@
using System.Linq;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.Storage.AccessCache;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Common;
using ModernKeePass.Pages;
namespace ModernKeePass.ViewModels
{
public class MainVm : NotifyPropertyChangedBase
{
private IOrderedEnumerable<IGrouping<int, MainMenuItemVm>> _mainMenuItems;
private MainMenuItemVm _selectedItem;
public IOrderedEnumerable<IGrouping<int, MainMenuItemVm>> MainMenuItems
{
get { return _mainMenuItems; }
set { SetProperty(ref _mainMenuItems, value); }
}
public MainMenuItemVm SelectedItem
{
get { return _selectedItem; }
set
{
if (_selectedItem == value) return;
if (_selectedItem != null)
{
_selectedItem.IsSelected = false;
}
SetProperty(ref _selectedItem, value);
if (_selectedItem != null)
{
_selectedItem.IsSelected = true;
}
}
}
public MainVm() {}
public MainVm(Frame referenceFrame, Frame destinationFrame)
{
var app = (App)Application.Current;
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
var mainMenuItems = new ObservableCollection<MainMenuItemVm>
{
new MainMenuItemVm {Title = "Open", PageType = typeof(OpenDatabasePage), Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Page2},
new MainMenuItemVm {Title = "New" /*, PageType = typeof(NewDatabasePage)*/, Destination = destinationFrame, SymbolIcon = Symbol.Add},
new MainMenuItemVm {Title = "Save" , PageType = typeof(SaveDatabasePage), Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Save},
new MainMenuItemVm {Title = "Recent" , PageType = typeof(RecentDatabasesPage), Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Copy,
IsSelected = (app.Database == null || !app.Database.IsOpen) && mru.Entries.Count > 0}
};
// Auto-select the Recent Items menu item if the conditions are met
SelectedItem = mainMenuItems.FirstOrDefault(m => m.IsSelected);
if (app.Database != null && app.Database.IsOpen)
mainMenuItems.Add(new MainMenuItemVm
{
Title = app.Database.Name,
PageType = typeof(GroupDetailPage),
Destination = referenceFrame,
Parameter = app.Database.RootGroup,
Group = 1,
SymbolIcon = Symbol.ProtectedDocument
});
MainMenuItems = from item in mainMenuItems group item by item.Group into grp orderby grp.Key select grp;
}
}
}

View File

@@ -1,4 +1,6 @@
using System.Collections.ObjectModel;
using System.Linq;
using Windows.Storage.AccessCache;
using ModernKeePass.Common;
namespace ModernKeePass.ViewModels
@@ -8,6 +10,16 @@ namespace ModernKeePass.ViewModels
private RecentItemVm _selectedItem;
private ObservableCollection<RecentItemVm> _recentItems;
public RecentVm()
{
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
RecentItems = new ObservableCollection<RecentItemVm>(
from entry in mru.Entries
select new RecentItemVm { Name = entry.Metadata, Token = entry.Token });
if (RecentItems.Count > 0)
SelectedItem = RecentItems[0];
}
public ObservableCollection<RecentItemVm> RecentItems
{
get { return _recentItems; }