From 1f04f941c20fd2d9b66566d840cfec83adaf47a6 Mon Sep 17 00:00:00 2001 From: Geoffroy BONNEVILLE Date: Thu, 4 Jun 2020 16:29:26 +0200 Subject: [PATCH] Corrected issue in color picker user control when changing history Use of commands instead of events in code-behind Some refactoring --- ModernKeePass/ViewModels/EntryDetailVm.cs | 160 +++++++++--------- ModernKeePass/ViewModels/GroupDetailVm.cs | 12 +- ModernKeePass/Views/EntryDetailPage.xaml | 9 +- ModernKeePass/Views/GroupDetailPage.xaml | 13 +- ModernKeePass/Views/GroupDetailPage.xaml.cs | 28 --- .../ColorPickerUserControl.xaml.cs | 6 +- .../UserControls/TopMenuUserControl.xaml.cs | 3 +- 7 files changed, 109 insertions(+), 122 deletions(-) diff --git a/ModernKeePass/ViewModels/EntryDetailVm.cs b/ModernKeePass/ViewModels/EntryDetailVm.cs index c3ee03d..efd1cd9 100644 --- a/ModernKeePass/ViewModels/EntryDetailVm.cs +++ b/ModernKeePass/ViewModels/EntryDetailVm.cs @@ -31,6 +31,7 @@ using ModernKeePass.Application.Group.Models; using ModernKeePass.Common; using ModernKeePass.Domain.Dtos; using ModernKeePass.Domain.Exceptions; +using ModernKeePass.Domain.Interfaces; using ModernKeePass.Extensions; using ModernKeePass.Models; using ModernKeePass.ViewModels.ListItems; @@ -39,9 +40,9 @@ namespace ModernKeePass.ViewModels { public class EntryDetailVm : ViewModelBase { - public bool HasExpired => HasExpirationDate && ExpiryDate < DateTime.Now; + public bool HasExpired => HasExpirationDate && ExpiryDate < _dateTime.Now; - public string Id => SelectedItem.Id; + public string Id => _current.Id; public string ParentGroupName => _parent.Title; @@ -62,37 +63,6 @@ namespace ModernKeePass.ViewModels /// Determines if the Entry is current or from history /// public bool IsCurrentEntry => SelectedIndex == 0; - - public EntryVm SelectedItem - { - get { return _selectedItem; } - set - { - Set(() => SelectedItem, ref _selectedItem, value, true); - if (value != null) - { - AdditionalFields = - new ObservableCollection( - SelectedItem.AdditionalFields.Select(f => - { - var field = new EntryFieldVm(_cryptography); - field.Initialize(f.Name, f.Value, f.IsProtected); - return field; - })); - - Attachments = new ObservableCollection(SelectedItem.Attachments.Select(f => new Attachment - { - Name = f.Key, - Content = f.Value - })); - Attachments.CollectionChanged += (sender, args) => - { - UpdateDirtyStatus(true); - }; - RaisePropertyChanged(string.Empty); - } - } - } public int SelectedIndex { @@ -117,33 +87,33 @@ namespace ModernKeePass.ViewModels public string Title { - get { return SelectedItem.Title.Value; } + get { return _current.Title.Value; } set { - SelectedItem.Title.Value = value; - SetFieldValue(SelectedItem.Title.Name, value, false).ConfigureAwait(false).GetAwaiter(); + _current.Title.Value = value; + SetFieldValue(_current.Title.Name, value, false).ConfigureAwait(false).GetAwaiter(); } } public string UserName { - get { return SelectedItem.Username.Value; } + get { return _current.Username.Value; } set { - SelectedItem.Username.Value = value; - SetFieldValue(SelectedItem.Username.Name, value, false).ConfigureAwait(false).GetAwaiter(); + _current.Username.Value = value; + SetFieldValue(_current.Username.Name, value, false).ConfigureAwait(false).GetAwaiter(); RaisePropertyChanged(nameof(UserName)); } } public string Password { - get { return _cryptography.UnProtect(SelectedItem.Password.Value).GetAwaiter().GetResult(); } + get { return _cryptography.UnProtect(_current.Password.Value).GetAwaiter().GetResult(); } set { var protectedPassword = _cryptography.Protect(value).ConfigureAwait(false).GetAwaiter().GetResult(); - SelectedItem.Password.Value = protectedPassword; - SetFieldValue(SelectedItem.Password.Name, protectedPassword, true).ConfigureAwait(false).GetAwaiter(); + _current.Password.Value = protectedPassword; + SetFieldValue(_current.Password.Name, protectedPassword, true).ConfigureAwait(false).GetAwaiter(); RaisePropertyChanged(nameof(Password)); } @@ -151,65 +121,65 @@ namespace ModernKeePass.ViewModels public string Url { - get { return SelectedItem.Url.Value; } + get { return _current.Url.Value; } set { - SelectedItem.Url.Value = value; - SetFieldValue(SelectedItem.Url.Name, value, false).ConfigureAwait(false).GetAwaiter(); + _current.Url.Value = value; + SetFieldValue(_current.Url.Name, value, false).ConfigureAwait(false).GetAwaiter(); RaisePropertyChanged(nameof(Url)); } } public string Notes { - get { return SelectedItem.Notes.Value; } + get { return _current.Notes.Value; } set { - SelectedItem.Notes.Value = value; - SetFieldValue(SelectedItem.Notes.Name, value, false).ConfigureAwait(false).GetAwaiter(); + _current.Notes.Value = value; + SetFieldValue(_current.Notes.Name, value, false).ConfigureAwait(false).GetAwaiter(); } } public Symbol Icon { - get { return (Symbol)Enum.Parse(typeof(Symbol), SelectedItem.Icon.ToString()); } + get { return (Symbol)Enum.Parse(typeof(Symbol), _current.Icon.ToString()); } set { - SelectedItem.Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString()); - SetFieldValue(EntryFieldName.Icon, SelectedItem.Icon, false).ConfigureAwait(false).GetAwaiter(); + _current.Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString()); + SetFieldValue(EntryFieldName.Icon, _current.Icon, false).ConfigureAwait(false).GetAwaiter(); } } public DateTimeOffset ExpiryDate { - get { return SelectedItem.ExpirationDate; } + get { return _current.ExpirationDate; } set { if (!HasExpirationDate) return; - SelectedItem.ExpirationDate = value.Date; - SetFieldValue(EntryFieldName.ExpirationDate, SelectedItem.ExpirationDate, false).ConfigureAwait(false).GetAwaiter(); + _current.ExpirationDate = value.Date; + SetFieldValue(EntryFieldName.ExpirationDate, _current.ExpirationDate, false).ConfigureAwait(false).GetAwaiter(); } } public TimeSpan ExpiryTime { - get { return SelectedItem.ExpirationDate.TimeOfDay; } + get { return _current.ExpirationDate.TimeOfDay; } set { if (!HasExpirationDate) return; - SelectedItem.ExpirationDate = SelectedItem.ExpirationDate.Date.Add(value); - SetFieldValue(EntryFieldName.ExpirationDate, SelectedItem.ExpirationDate, false).ConfigureAwait(false).GetAwaiter(); + _current.ExpirationDate = _current.ExpirationDate.Date.Add(value); + SetFieldValue(EntryFieldName.ExpirationDate, _current.ExpirationDate, false).ConfigureAwait(false).GetAwaiter(); } } public bool HasExpirationDate { - get { return SelectedItem.HasExpirationDate; } + get { return _current.HasExpirationDate; } set { - SelectedItem.HasExpirationDate = value; + _current.HasExpirationDate = value; SetFieldValue(EntryFieldName.HasExpirationDate, value, false).ConfigureAwait(false).GetAwaiter(); RaisePropertyChanged(nameof(HasExpirationDate)); } @@ -217,21 +187,21 @@ namespace ModernKeePass.ViewModels public SolidColorBrush BackgroundColor { - get { return SelectedItem?.BackgroundColor.ToSolidColorBrush(); } + get { return _current?.BackgroundColor.ToSolidColorBrush(); } set { - SelectedItem.BackgroundColor = value.ToColor(); - SetFieldValue(EntryFieldName.BackgroundColor, SelectedItem.BackgroundColor, false).ConfigureAwait(false).GetAwaiter(); + _current.BackgroundColor = value.ToColor(); + SetFieldValue(EntryFieldName.BackgroundColor, _current.BackgroundColor, false).ConfigureAwait(false).GetAwaiter(); } } public SolidColorBrush ForegroundColor { - get { return SelectedItem?.ForegroundColor.ToSolidColorBrush(); } + get { return _current?.ForegroundColor.ToSolidColorBrush(); } set { - SelectedItem.ForegroundColor = value.ToColor(); - SetFieldValue(EntryFieldName.ForegroundColor, SelectedItem.ForegroundColor, false).ConfigureAwait(false).GetAwaiter(); + _current.ForegroundColor = value.ToColor(); + SetFieldValue(EntryFieldName.ForegroundColor, _current.ForegroundColor, false).ConfigureAwait(false).GetAwaiter(); } } @@ -246,12 +216,13 @@ namespace ModernKeePass.ViewModels public RelayCommand RestoreCommand { get; } public RelayCommand DeleteCommand { get; } public RelayCommand GoBackCommand { get; } - public RelayCommand GoToParentCommand { get; set; } - public RelayCommand AddAdditionalField { get; set; } - public RelayCommand DeleteAdditionalField { get; set; } - public RelayCommand OpenAttachmentCommand { get; set; } - public RelayCommand AddAttachmentCommand { get; set; } - public RelayCommand DeleteAttachmentCommand { get; set; } + public RelayCommand GoToParentCommand { get; } + public RelayCommand AddAdditionalField { get; } + public RelayCommand DeleteAdditionalField { get; } + public RelayCommand OpenAttachmentCommand { get; } + public RelayCommand AddAttachmentCommand { get; } + public RelayCommand DeleteAttachmentCommand { get; } + public RelayCommand SetCurrentEntryCommand { get; } private DatabaseVm Database => _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult(); @@ -262,14 +233,15 @@ namespace ModernKeePass.ViewModels private readonly INotificationService _notification; private readonly IFileProxy _file; private readonly ICryptographyClient _cryptography; + private readonly IDateTime _dateTime; private GroupVm _parent; - private EntryVm _selectedItem; + private EntryVm _current; private int _selectedIndex; private int _additionalFieldSelectedIndex = -1; private bool _isEditMode; private bool _isDirty; - public EntryDetailVm(IMediator mediator, INavigationService navigation, IResourceProxy resource, IDialogService dialog, INotificationService notification, IFileProxy file, ICryptographyClient cryptography) + public EntryDetailVm(IMediator mediator, INavigationService navigation, IResourceProxy resource, IDialogService dialog, INotificationService notification, IFileProxy file, ICryptographyClient cryptography, IDateTime dateTime) { _mediator = mediator; _navigation = navigation; @@ -278,6 +250,7 @@ namespace ModernKeePass.ViewModels _notification = notification; _file = file; _cryptography = cryptography; + _dateTime = dateTime; SaveCommand = new RelayCommand(async () => await SaveChanges(), () => Database.IsDirty); MoveCommand = new RelayCommand(async destination => await Move(destination), destination => _parent != null && !string.IsNullOrEmpty(destination) && destination != _parent.Id); @@ -290,6 +263,7 @@ namespace ModernKeePass.ViewModels OpenAttachmentCommand = new RelayCommand(async attachment => await OpenAttachment(attachment)); AddAttachmentCommand = new RelayCommand(async () => await AddAttachment(), () => IsCurrentEntry); DeleteAttachmentCommand = new RelayCommand(async attachment => await DeleteAttachment(attachment), _ => IsCurrentEntry); + SetCurrentEntryCommand = new RelayCommand(SetCurrentEntry, entry => entry != null); MessengerInstance.Register(this, _ => SaveCommand.RaiseCanExecuteChanged()); MessengerInstance.Register(this, async message => await SetFieldValue(message.FieldName, message.FieldValue, message.IsProtected)); @@ -300,10 +274,10 @@ namespace ModernKeePass.ViewModels public async Task Initialize(string entryId) { SelectedIndex = 0; - SelectedItem = await _mediator.Send(new GetEntryQuery { Id = entryId }); - _parent = await _mediator.Send(new GetGroupQuery { Id = SelectedItem.ParentGroupId }); - History = new ObservableCollection { SelectedItem }; - foreach (var entry in SelectedItem.History.Skip(1)) + _current = await _mediator.Send(new GetEntryQuery { Id = entryId }); + _parent = await _mediator.Send(new GetGroupQuery { Id = _current.ParentGroupId }); + History = new ObservableCollection { _current }; + foreach (var entry in _current.History.Skip(1)) { History.Add(entry); } @@ -398,7 +372,7 @@ namespace ModernKeePass.ViewModels private async Task RestoreHistory() { await _mediator.Send(new RestoreHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex - 1 }); - History.Insert(0, SelectedItem); + History.Insert(0, _current); } private async Task SaveChanges() @@ -420,7 +394,7 @@ namespace ModernKeePass.ViewModels await _mediator.Send(new DeleteEntryCommand { EntryId = Id, - ParentGroupId = SelectedItem.ParentGroupId, + ParentGroupId = _current.ParentGroupId, RecycleBinName = _resource.GetResourceValue("RecycleBinTitle") }); _isDirty = false; @@ -443,13 +417,13 @@ namespace ModernKeePass.ViewModels var fileInfo = await _file.OpenFile(string.Empty, Domain.Common.Constants.Extensions.Any, false); if (fileInfo == null) return; var contents = await _file.ReadBinaryFile(fileInfo.Id); - await _mediator.Send(new AddAttachmentCommand { Entry = SelectedItem, AttachmentName = fileInfo.Name, AttachmentContent = contents }); + await _mediator.Send(new AddAttachmentCommand { Entry = _current, AttachmentName = fileInfo.Name, AttachmentContent = contents }); Attachments.Add(new Attachment { Name = fileInfo.Name, Content = contents }); } private async Task DeleteAttachment(Attachment attachment) { - await _mediator.Send(new DeleteAttachmentCommand { Entry = SelectedItem, AttachmentName = attachment.Name }); + await _mediator.Send(new DeleteAttachmentCommand { Entry = _current, AttachmentName = attachment.Name }); Attachments.Remove(attachment); } @@ -458,5 +432,29 @@ namespace ModernKeePass.ViewModels SaveCommand.RaiseCanExecuteChanged(); _isDirty = isDirty; } + + private void SetCurrentEntry(EntryVm entry) + { + _current = entry; + AdditionalFields = + new ObservableCollection( + entry.AdditionalFields.Select(f => + { + var field = new EntryFieldVm(_cryptography); + field.Initialize(f.Name, f.Value, f.IsProtected); + return field; + })); + + Attachments = new ObservableCollection(entry.Attachments.Select(f => new Attachment + { + Name = f.Key, + Content = f.Value + })); + Attachments.CollectionChanged += (sender, args) => + { + UpdateDirtyStatus(true); + }; + RaisePropertyChanged(string.Empty); + } } } diff --git a/ModernKeePass/ViewModels/GroupDetailVm.cs b/ModernKeePass/ViewModels/GroupDetailVm.cs index 21d5a6e..9da777c 100644 --- a/ModernKeePass/ViewModels/GroupDetailVm.cs +++ b/ModernKeePass/ViewModels/GroupDetailVm.cs @@ -92,9 +92,11 @@ namespace ModernKeePass.ViewModels public RelayCommand MoveCommand { get; } public RelayCommand CreateEntryCommand { get; } public RelayCommand CreateGroupCommand { get; } - public RelayCommand DeleteCommand { get; set; } - public RelayCommand GoBackCommand { get; set; } - public RelayCommand GoToParentCommand { get; set; } + public RelayCommand DeleteCommand { get; } + public RelayCommand GoBackCommand { get; } + public RelayCommand GoToParentCommand { get; } + public RelayCommand GoToGroupCommand { get; } + public RelayCommand GoToEntryCommand { get; } private DatabaseVm Database => _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult(); @@ -125,7 +127,9 @@ namespace ModernKeePass.ViewModels CreateGroupCommand = new RelayCommand(async newGroupName => await AddNewGroup(newGroupName), _ => !IsInRecycleBin && Database.RecycleBinId != Id); DeleteCommand = new RelayCommand(async () => await AskForDelete(),() => IsNotRoot); GoBackCommand = new RelayCommand(() => _navigation.GoBack()); - GoToParentCommand= new RelayCommand(() => GoToGroup(_parent.Id), () => _parent != null); + GoToParentCommand = new RelayCommand(() => GoToGroup(_parent.Id), () => _parent != null); + GoToGroupCommand = new RelayCommand(group => GoToGroup(group.Id), group => group != null); + GoToEntryCommand = new RelayCommand(entry => GoToEntry(entry.Id), entry => entry != null); MessengerInstance.Register(this, _ => SaveCommand.RaiseCanExecuteChanged()); } diff --git a/ModernKeePass/Views/EntryDetailPage.xaml b/ModernKeePass/Views/EntryDetailPage.xaml index d0a3616..e363082 100644 --- a/ModernKeePass/Views/EntryDetailPage.xaml +++ b/ModernKeePass/Views/EntryDetailPage.xaml @@ -208,8 +208,13 @@ x:Name="HamburgerMenu" x:Uid="HistoryLeftListView" ItemsSource="{Binding History}" - SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}" - SelectedItem="{Binding SelectedItem, Mode=TwoWay}" /> + SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}"> + + + + + + diff --git a/ModernKeePass/Views/GroupDetailPage.xaml b/ModernKeePass/Views/GroupDetailPage.xaml index a022c80..2875e75 100644 --- a/ModernKeePass/Views/GroupDetailPage.xaml +++ b/ModernKeePass/Views/GroupDetailPage.xaml @@ -72,7 +72,6 @@ AutomationProperties.AutomationId="ItemGridView" AutomationProperties.Name="Entries" TabIndex="1" - SelectionChanged="entries_SelectionChanged" IsSynchronizedWithCurrentItem="False" BorderBrush="{StaticResource ListViewItemSelectedBackgroundThemeBrush}" AllowDrop="True" @@ -82,6 +81,9 @@ + + + @@ -174,9 +176,14 @@ x:Uid="GroupsLeftListView" ItemsSource="{Binding Groups}" CanDragItems="{Binding IsEditMode}" - SelectionChanged="groups_SelectionChanged" ActionButtonCommand="{Binding CreateGroupCommand}" - IsButtonVisible="Visible" /> + IsButtonVisible="Visible"> + + + + + + diff --git a/ModernKeePass/Views/GroupDetailPage.xaml.cs b/ModernKeePass/Views/GroupDetailPage.xaml.cs index f2fb235..44ba8d3 100644 --- a/ModernKeePass/Views/GroupDetailPage.xaml.cs +++ b/ModernKeePass/Views/GroupDetailPage.xaml.cs @@ -1,7 +1,6 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; -using ModernKeePass.Application.Entry.Models; using ModernKeePass.Models; using ModernKeePass.ViewModels; @@ -37,33 +36,6 @@ namespace ModernKeePass.Views #endregion #region Event Handlers - - private void groups_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - var listView = sender as ListView; - switch (listView?.SelectedIndex) - { - case -1: - return; - default: - var group = listView?.SelectedItem as Application.Group.Models.GroupVm; - Model.GoToGroup(group?.Id); - break; - } - } - - private void entries_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - switch (GridView.SelectedIndex) - { - case -1: - return; - default: - var entry = GridView.SelectedItem as EntryVm; - Model.GoToEntry(entry?.Id); - break; - } - } private void SemanticZoom_ViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e) { diff --git a/ModernKeePass/Views/UserControls/ColorPickerUserControl.xaml.cs b/ModernKeePass/Views/UserControls/ColorPickerUserControl.xaml.cs index 0db9e59..cbdf1c2 100644 --- a/ModernKeePass/Views/UserControls/ColorPickerUserControl.xaml.cs +++ b/ModernKeePass/Views/UserControls/ColorPickerUserControl.xaml.cs @@ -1,4 +1,5 @@ -using Windows.UI.Xaml; +using System.Linq; +using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; using ModernKeePass.ViewModels; @@ -33,7 +34,8 @@ namespace ModernKeePass.Views.UserControls private void ComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { - SelectedColor = (e.AddedItems[0] as ColorPickerControlVm.Color)?.ColorBrush; + if (e.AddedItems.Any()) + SelectedColor = (e.AddedItems[0] as ColorPickerControlVm.Color)?.ColorBrush; } } } diff --git a/ModernKeePass/Views/UserControls/TopMenuUserControl.xaml.cs b/ModernKeePass/Views/UserControls/TopMenuUserControl.xaml.cs index 7136519..a0dde29 100644 --- a/ModernKeePass/Views/UserControls/TopMenuUserControl.xaml.cs +++ b/ModernKeePass/Views/UserControls/TopMenuUserControl.xaml.cs @@ -213,8 +213,7 @@ namespace ModernKeePass.Views.UserControls MoveButton.CommandParameter = args.Tag; MoveCommand.RaiseCanExecuteChanged(); } - - + private async void EntrySearchBox_OnSuggestionsRequested(SearchBox sender, SearchBoxSuggestionsRequestedEventArgs args) { var imageUri = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appdata:/Assets/ModernKeePass-SmallLogo.scale-80.png"));