Layout change in CompositeKey user control

Button text is now settable
Opening database is placed in async task dispatcher to return control to the UI
This commit is contained in:
BONNEVILLE Geoffroy
2017-11-24 18:21:06 +01:00
parent 7cd05cb1d8
commit 42ac04b02c
11 changed files with 98 additions and 15 deletions

View File

@@ -9,15 +9,14 @@
xmlns:actions="using:ModernKeePass.Actions" xmlns:actions="using:ModernKeePass.Actions"
xmlns:converters="using:ModernKeePass.Converters" xmlns:converters="using:ModernKeePass.Converters"
xmlns:viewModels="using:ModernKeePass.ViewModels" xmlns:viewModels="using:ModernKeePass.ViewModels"
mc:Ignorable="d" mc:Ignorable="d" >
d:DesignHeight="120"
d:DesignWidth="550" >
<UserControl.Resources> <UserControl.Resources>
<SolidColorBrush x:Key="ErrorColorBrush" Color="Red"/> <SolidColorBrush x:Key="ErrorColorBrush" Color="Red"/>
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/> <converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushConverter"/> <converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushConverter"/>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<converters:DiscreteIntToSolidColorBrushConverter x:Key="DiscreteIntToSolidColorBrushConverter"/> <converters:DiscreteIntToSolidColorBrushConverter x:Key="DiscreteIntToSolidColorBrushConverter"/>
<converters:EmptyStringToVisibilityConverter x:Key="EmptyStringToVisibilityConverter"/>
</UserControl.Resources> </UserControl.Resources>
<Grid x:Name="Grid"> <Grid x:Name="Grid">
<!-- DataContext is not set at the root of the control because of issues happening when displaying it --> <!-- DataContext is not set at the root of the control because of issues happening when displaying it -->
@@ -31,6 +30,7 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="45" /> <RowDefinition Height="45" />
<RowDefinition Height="40" /> <RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding HasPassword, Mode=TwoWay}" /> <CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding HasPassword, Mode=TwoWay}" />
@@ -49,9 +49,13 @@
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" /> <CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" />
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0" Content="{Binding KeyFileText}" IsEnabled="{Binding HasKeyFile}" Click="KeyFileButton_Click" /> <HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0" Content="{Binding KeyFileText}" IsEnabled="{Binding HasKeyFile}" Click="KeyFileButton_Click" />
<HyperlinkButton Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Visibility="{Binding ShowComplexityIndicator, ElementName=UserControl, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding HasKeyFile}" Click="CreateKeyFileButton_Click"> <HyperlinkButton Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Visibility="{Binding ShowComplexityIndicator, ElementName=UserControl, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding HasKeyFile}" Click="CreateKeyFileButton_Click">
<SymbolIcon Symbol="Add" /> <SymbolIcon Symbol="Add">
<ToolTipService.ToolTip>
<ToolTip Content="Create new key file" />
</ToolTipService.ToolTip>
</SymbolIcon>
</HyperlinkButton> </HyperlinkButton>
<Button Grid.Column="0" Grid.Row="2" Content="OK" Click="OpenButton_OnClick" Background="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" Foreground="{ThemeResource TextBoxBackgroundThemeBrush}" IsEnabled="{Binding IsValid}" /> <TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="28" FontSize="14" FontWeight="Light" Text="{Binding Status}" Foreground="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" Visibility="{Binding Status, Converter={StaticResource EmptyStringToVisibilityConverter}}" />
<TextBlock Grid.Column="1" Grid.Row="2" Height="28" FontSize="14" FontWeight="Light" HorizontalAlignment="Right" Text="{Binding Status}" Foreground="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" /> <Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" Content="{Binding ButtonLabel, ElementName=UserControl}" Click="OpenButton_OnClick" Background="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" Foreground="{ThemeResource TextBoxBackgroundThemeBrush}" IsEnabled="{Binding IsValid}" />
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -1,10 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage.Pickers; using Windows.Storage.Pickers;
using Windows.System; using Windows.System;
using Windows.UI.Core;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Input;
using ModernKeePass.Events; using ModernKeePass.Events;
using ModernKeePass.Extensions;
using ModernKeePass.ViewModels; using ModernKeePass.ViewModels;
// Pour en savoir plus sur le modèle d'élément Contrôle utilisateur, consultez la page http://go.microsoft.com/fwlink/?LinkId=234236 // Pour en savoir plus sur le modèle d'élément Contrôle utilisateur, consultez la page http://go.microsoft.com/fwlink/?LinkId=234236
@@ -39,6 +42,19 @@ namespace ModernKeePass.Controls
typeof(CompositeKeyUserControl), typeof(CompositeKeyUserControl),
new PropertyMetadata(false, (o, args) => { })); new PropertyMetadata(false, (o, args) => { }));
public string ButtonLabel
{
get { return (string)GetValue(ButtonLabelProperty); }
set { SetValue(ButtonLabelProperty, value); }
}
public static readonly DependencyProperty ButtonLabelProperty =
DependencyProperty.Register(
"ButtonLabel",
typeof(string),
typeof(CompositeKeyUserControl),
new PropertyMetadata("OK", (o, args) => { }));
public bool ShowComplexityIndicator => CreateNew || UpdateKey; public bool ShowComplexityIndicator => CreateNew || UpdateKey;
public CompositeKeyUserControl() public CompositeKeyUserControl()
@@ -51,14 +67,20 @@ namespace ModernKeePass.Controls
public event PasswordCheckedEventHandler ValidationChecked; public event PasswordCheckedEventHandler ValidationChecked;
public delegate void PasswordCheckedEventHandler(object sender, PasswordEventArgs e); public delegate void PasswordCheckedEventHandler(object sender, PasswordEventArgs e);
private void OpenButton_OnClick(object sender, RoutedEventArgs e) private async void OpenButton_OnClick(object sender, RoutedEventArgs e)
{ {
ValidationChecking?.Invoke(this, new EventArgs()); ValidationChecking?.Invoke(this, new EventArgs());
if (UpdateKey) Model.UpdateKey(); if (UpdateKey) Model.UpdateKey();
else if (Model.OpenDatabase(CreateNew)) else
{ {
ValidationChecked?.Invoke(this, new PasswordEventArgs(Model.RootGroup)); var oldLabel = ButtonLabel;
ButtonLabel = "Opening...";
if (await Dispatcher.RunTaskAsync(async () => await Model.OpenDatabase(CreateNew)))
{
ValidationChecked?.Invoke(this, new PasswordEventArgs(Model.RootGroup));
}
ButtonLabel = oldLabel;
} }
} }

View File

@@ -0,0 +1,20 @@
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
namespace ModernKeePass.Converters
{
class EmptyStringToVisibilityConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var text = value is string ? value.ToString() : string.Empty;
return string.IsNullOrEmpty(text) ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Threading.Tasks;
using Windows.UI.Core;
namespace ModernKeePass.Extensions
{
public static class DispatcherTaskExtensions
{
public static async Task<T> RunTaskAsync<T>(this CoreDispatcher dispatcher,
Func<Task<T>> func, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
var taskCompletionSource = new TaskCompletionSource<T>();
await dispatcher.RunAsync(priority, async () =>
{
try
{
taskCompletionSource.SetResult(await func());
}
catch (Exception ex)
{
taskCompletionSource.SetException(ex);
}
});
return await taskCompletionSource.Task;
}
// There is no TaskCompletionSource<void> so we use a bool that we throw away.
public static async Task RunTaskAsync(this CoreDispatcher dispatcher,
Func<Task> func, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal) =>
await RunTaskAsync(dispatcher, async () => { await func(); return false; }, priority);
}
}

View File

@@ -122,8 +122,10 @@
<Compile Include="Common\SuspensionManager.cs" /> <Compile Include="Common\SuspensionManager.cs" />
<Compile Include="Common\ToastNotificationHelper.cs" /> <Compile Include="Common\ToastNotificationHelper.cs" />
<Compile Include="Converters\DiscreteIntToSolidColorBrushConverter.cs" /> <Compile Include="Converters\DiscreteIntToSolidColorBrushConverter.cs" />
<Compile Include="Converters\EmptyStringToVisibilityConverter.cs" />
<Compile Include="Converters\NullToBooleanConverter.cs" /> <Compile Include="Converters\NullToBooleanConverter.cs" />
<Compile Include="Exceptions\SaveException.cs" /> <Compile Include="Exceptions\SaveException.cs" />
<Compile Include="Extensions\DispatcherTaskExtensions.cs" />
<Compile Include="Interfaces\IDatabase.cs" /> <Compile Include="Interfaces\IDatabase.cs" />
<Compile Include="Interfaces\IHasSelectableObject.cs" /> <Compile Include="Interfaces\IHasSelectableObject.cs" />
<Compile Include="Interfaces\ISelectableModel.cs" /> <Compile Include="Interfaces\ISelectableModel.cs" />

View File

@@ -23,7 +23,7 @@
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding ShowPasswordBox, Converter={StaticResource BooleanToVisibilityConverter}}"> <Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding ShowPasswordBox, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0"> <StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" /> <TextBlock Text="{Binding Name}" />
<local:CompositeKeyUserControl CreateNew="True" > <local:CompositeKeyUserControl CreateNew="True" ButtonLabel="Save" >
<interactivity:Interaction.Behaviors> <interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ValidationChecked"> <core:EventTriggerBehavior EventName="ValidationChecked">
<core:NavigateToPageAction TargetPage="ModernKeePass.Pages.GroupDetailPage" /> <core:NavigateToPageAction TargetPage="ModernKeePass.Pages.GroupDetailPage" />

View File

@@ -24,7 +24,7 @@
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding ShowPasswordBox, Converter={StaticResource BooleanToVisibilityConverter}}"> <Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding ShowPasswordBox, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0"> <StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" /> <TextBlock Text="{Binding Name}" />
<local:CompositeKeyUserControl> <local:CompositeKeyUserControl ButtonLabel="Open">
<interactivity:Interaction.Behaviors> <interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ValidationChecked"> <Core:EventTriggerBehavior EventName="ValidationChecked">
<Core:NavigateToPageAction TargetPage="ModernKeePass.Pages.GroupDetailPage" /> <Core:NavigateToPageAction TargetPage="ModernKeePass.Pages.GroupDetailPage" />

View File

@@ -34,7 +34,7 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Name}" Padding="5,0,0,0" /> <TextBlock Grid.Row="0" Text="{Binding Name}" Padding="5,0,0,0" />
<TextBlock Grid.Row="1" Text="{Binding Path}" Padding="5,0,0,0" FontSize="10" /> <TextBlock Grid.Row="1" Text="{Binding Path}" Padding="5,0,0,0" FontSize="10" />
<local:CompositeKeyUserControl Grid.Row="2" x:Name="DatabaseUserControl" HorizontalAlignment="Stretch" MinWidth="400" Margin="0,10,0,0" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}"> <local:CompositeKeyUserControl Grid.Row="2" x:Name="DatabaseUserControl" HorizontalAlignment="Stretch" MinWidth="400" Margin="0,10,0,0" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" ButtonLabel="Open">
<interactivity:Interaction.Behaviors> <interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ValidationChecking"> <core:EventTriggerBehavior EventName="ValidationChecking">
<core:CallMethodAction TargetObject="{Binding}" MethodName="OpenDatabaseFile" /> <core:CallMethodAction TargetObject="{Binding}" MethodName="OpenDatabaseFile" />

View File

@@ -9,6 +9,6 @@
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Text="Change database security options" /> <TextBlock Text="Change database security options" />
<local:CompositeKeyUserControl UpdateKey="True" /> <local:CompositeKeyUserControl UpdateKey="True" ButtonLabel="Update master key" />
</StackPanel> </StackPanel>
</Page> </Page>

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Text; using System.Text;
using System.Threading.Tasks;
using Windows.Storage; using Windows.Storage;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using ModernKeePass.Common; using ModernKeePass.Common;
@@ -73,6 +74,7 @@ namespace ModernKeePass.ViewModels
_password = value; _password = value;
OnPropertyChanged("PasswordComplexityIndicator"); OnPropertyChanged("PasswordComplexityIndicator");
StatusType = (int)StatusTypes.Normal; StatusType = (int)StatusTypes.Normal;
Status = string.Empty;
} }
} }
@@ -104,7 +106,7 @@ namespace ModernKeePass.ViewModels
Database = database; Database = database;
} }
public bool OpenDatabase(bool createNew) public async Task<bool> OpenDatabase(bool createNew)
{ {
var error = string.Empty; var error = string.Empty;
try try
@@ -118,7 +120,7 @@ namespace ModernKeePass.ViewModels
switch ((DatabaseHelper.DatabaseStatus)Database.Status) switch ((DatabaseHelper.DatabaseStatus)Database.Status)
{ {
case DatabaseHelper.DatabaseStatus.Opened: case DatabaseHelper.DatabaseStatus.Opened:
RootGroup = Database.RootGroup; await Task.Run( () => RootGroup = Database.RootGroup);
return true; return true;
case DatabaseHelper.DatabaseStatus.CompositeKeyError: case DatabaseHelper.DatabaseStatus.CompositeKeyError:
var errorMessage = new StringBuilder("Error: wrong "); var errorMessage = new StringBuilder("Error: wrong ");

View File

@@ -1,6 +1,7 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using Windows.UI.Text; using Windows.UI.Text;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;