mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
Additional fields Add, Update and Delete work (too well)
SelectableListView works when programmatically setting selection
This commit is contained in:
@@ -91,6 +91,7 @@
|
||||
<Compile Include="Entry\Commands\AddAttachment\AddAttachmentCommand.cs" />
|
||||
<Compile Include="Entry\Commands\AddHistory\AddHistoryCommand.cs" />
|
||||
<Compile Include="Entry\Commands\DeleteAttachment\DeleteAttachmentCommand.cs" />
|
||||
<Compile Include="Entry\Commands\DeleteField\DeleteFieldCommand.cs" />
|
||||
<Compile Include="Entry\Commands\DeleteHistory\DeleteHistoryCommand.cs" />
|
||||
<Compile Include="Entry\Commands\RestoreHistory\RestoreHistoryCommand.cs" />
|
||||
<Compile Include="Entry\Queries\GetEntry\GetEntryQuery.cs" />
|
||||
@@ -121,8 +122,8 @@
|
||||
<Compile Include="Database\Queries\OpenDatabase\OpenDatabaseQueryValidator.cs" />
|
||||
<Compile Include="Database\Queries\ReOpenDatabase\ReOpenDatabaseQuery.cs" />
|
||||
<Compile Include="DependencyInjection.cs" />
|
||||
<Compile Include="Entry\Commands\SetFieldValue\SetFieldValueCommand.cs" />
|
||||
<Compile Include="Entry\Commands\SetFieldValue\SetFieldValueCommandValidator.cs" />
|
||||
<Compile Include="Entry\Commands\UpsertField\UpsertFieldCommand.cs" />
|
||||
<Compile Include="Entry\Commands\UpsertField\UpsertFieldCommandValidator.cs" />
|
||||
<Compile Include="Entry\Models\EntryVm.cs" />
|
||||
<Compile Include="Group\Commands\AddEntry\AddEntryCommand.cs" />
|
||||
<Compile Include="Group\Commands\AddGroup\AddGroupCommand.cs" />
|
||||
|
@@ -31,19 +31,22 @@ namespace ModernKeePass.Application.Common.Interfaces
|
||||
void CloseDatabase();
|
||||
|
||||
EntryEntity GetEntry(string id);
|
||||
GroupEntity GetGroup(string id);
|
||||
Task AddEntry(string parentGroupId, string entryId);
|
||||
Task MoveEntry(string parentGroupId, string entryId, int index);
|
||||
Task AddGroup(string parentGroupId, string groupId);
|
||||
void UpdateEntry(string entryId, string fieldName, object fieldValue);
|
||||
void UpdateGroup(GroupEntity group);
|
||||
void DeleteField(string entryId, string fieldName);
|
||||
Task RemoveEntry(string parentGroupId, string entryId);
|
||||
EntryEntity CreateEntry(string parentGroupId);
|
||||
void SortEntries(string groupId);
|
||||
|
||||
GroupEntity GetGroup(string id);
|
||||
Task AddGroup(string parentGroupId, string groupId);
|
||||
void UpdateGroup(GroupEntity group);
|
||||
Task RemoveGroup(string parentGroupId, string groupId);
|
||||
void DeleteEntity(string entityId);
|
||||
EntryEntity CreateEntry(string parentGroupId);
|
||||
GroupEntity CreateGroup(string parentGroupId, string name, bool isRecycleBin = false);
|
||||
void SortEntries(string groupId);
|
||||
void SortSubGroups(string groupId);
|
||||
|
||||
void AddAttachment(string entryId, string attachmentName, byte[] attachmentContent);
|
||||
void DeleteAttachment(string entryId, string attachmentName);
|
||||
|
||||
|
@@ -0,0 +1,29 @@
|
||||
using MediatR;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Domain.Exceptions;
|
||||
|
||||
namespace ModernKeePass.Application.Entry.Commands.DeleteField
|
||||
{
|
||||
public class DeleteFieldCommand: IRequest
|
||||
{
|
||||
public string EntryId { get; set; }
|
||||
public string FieldName { get; set; }
|
||||
|
||||
public class DeleteFieldCommandHandler : IRequestHandler<DeleteFieldCommand>
|
||||
{
|
||||
private readonly IDatabaseProxy _database;
|
||||
|
||||
public DeleteFieldCommandHandler(IDatabaseProxy database)
|
||||
{
|
||||
_database = database;
|
||||
}
|
||||
|
||||
public void Handle(DeleteFieldCommand message)
|
||||
{
|
||||
if (!_database.IsOpen) throw new DatabaseClosedException();
|
||||
|
||||
_database.DeleteField(message.EntryId, message.FieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,24 +2,24 @@
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Domain.Exceptions;
|
||||
|
||||
namespace ModernKeePass.Application.Entry.Commands.SetFieldValue
|
||||
namespace ModernKeePass.Application.Entry.Commands.UpsertField
|
||||
{
|
||||
public class SetFieldValueCommand : IRequest
|
||||
public class UpsertFieldCommand : IRequest
|
||||
{
|
||||
public string EntryId { get; set; }
|
||||
public string FieldName { get; set; }
|
||||
public object FieldValue { get; set; }
|
||||
|
||||
public class SetFieldValueCommandHandler : IRequestHandler<SetFieldValueCommand>
|
||||
public class UpsertFieldCommandHandler : IRequestHandler<UpsertFieldCommand>
|
||||
{
|
||||
private readonly IDatabaseProxy _database;
|
||||
|
||||
public SetFieldValueCommandHandler(IDatabaseProxy database)
|
||||
public UpsertFieldCommandHandler(IDatabaseProxy database)
|
||||
{
|
||||
_database = database;
|
||||
}
|
||||
|
||||
public void Handle(SetFieldValueCommand message)
|
||||
public void Handle(UpsertFieldCommand message)
|
||||
{
|
||||
if (!_database.IsOpen) throw new DatabaseClosedException();
|
||||
|
@@ -1,10 +1,10 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace ModernKeePass.Application.Entry.Commands.SetFieldValue
|
||||
namespace ModernKeePass.Application.Entry.Commands.UpsertField
|
||||
{
|
||||
public class SetFieldValueCommandValidator: AbstractValidator<SetFieldValueCommand>
|
||||
public class UpsertFieldCommandValidator: AbstractValidator<UpsertFieldCommand>
|
||||
{
|
||||
public SetFieldValueCommandValidator()
|
||||
public UpsertFieldCommandValidator()
|
||||
{
|
||||
RuleFor(v => v.EntryId)
|
||||
.NotNull()
|
@@ -78,7 +78,6 @@
|
||||
<Compile Include="Common\Constants.cs" />
|
||||
<Compile Include="Dtos\Attachment.cs" />
|
||||
<Compile Include="Dtos\Credentials.cs" />
|
||||
<Compile Include="Dtos\Field.cs" />
|
||||
<Compile Include="Dtos\FileInfo.cs" />
|
||||
<Compile Include="Dtos\PasswordGenerationOptions.cs" />
|
||||
<Compile Include="Entities\BaseEntity.cs" />
|
||||
|
@@ -1,8 +0,0 @@
|
||||
namespace ModernKeePass.Domain.Dtos
|
||||
{
|
||||
public class Field
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
@@ -242,9 +242,18 @@ namespace ModernKeePass.Infrastructure.KeePass
|
||||
case EntryFieldName.ForegroundColor:
|
||||
pwEntry.ForegroundColor = (Color)fieldValue;
|
||||
break;
|
||||
default:
|
||||
pwEntry.Strings.Set(fieldName, new ProtectedString(true, fieldValue.ToString()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteField(string entryId, string fieldName)
|
||||
{
|
||||
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||
pwEntry.Strings.Remove(fieldName);
|
||||
}
|
||||
|
||||
public EntryEntity AddHistory(string entryId)
|
||||
{
|
||||
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||
|
@@ -534,4 +534,10 @@
|
||||
<data name="EntryAddAttachment.Text" xml:space="preserve">
|
||||
<value>Add attachment</value>
|
||||
</data>
|
||||
<data name="EntryAddAdditionalField.Text" xml:space="preserve">
|
||||
<value>Add field</value>
|
||||
</data>
|
||||
<data name="EntryDeleteAdditionalField.Content" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
</data>
|
||||
</root>
|
@@ -276,4 +276,7 @@
|
||||
<data name="CompositeKeyFileNameSuggestion" xml:space="preserve">
|
||||
<value>Clé</value>
|
||||
</data>
|
||||
<data name="EntryAddAdditionalField.Text" xml:space="preserve">
|
||||
<value>Ajouter un champ</value>
|
||||
</data>
|
||||
</root>
|
@@ -534,4 +534,7 @@
|
||||
<data name="EntryAddAttachment.Text" xml:space="preserve">
|
||||
<value>Ajouter une pièce jointe</value>
|
||||
</data>
|
||||
<data name="EntryDeleteAdditionalField.Content" xml:space="preserve">
|
||||
<value>Supprimer</value>
|
||||
</data>
|
||||
</root>
|
@@ -16,9 +16,10 @@ using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||
using ModernKeePass.Application.Entry.Commands.AddAttachment;
|
||||
using ModernKeePass.Application.Entry.Commands.AddHistory;
|
||||
using ModernKeePass.Application.Entry.Commands.DeleteAttachment;
|
||||
using ModernKeePass.Application.Entry.Commands.DeleteField;
|
||||
using ModernKeePass.Application.Entry.Commands.DeleteHistory;
|
||||
using ModernKeePass.Application.Entry.Commands.RestoreHistory;
|
||||
using ModernKeePass.Application.Entry.Commands.SetFieldValue;
|
||||
using ModernKeePass.Application.Entry.Commands.UpsertField;
|
||||
using ModernKeePass.Application.Entry.Models;
|
||||
using ModernKeePass.Application.Entry.Queries.GetEntry;
|
||||
using ModernKeePass.Application.Group.Commands.AddEntry;
|
||||
@@ -34,6 +35,7 @@ using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.Domain.Exceptions;
|
||||
using ModernKeePass.Extensions;
|
||||
using ModernKeePass.Models;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
@@ -66,7 +68,7 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
|
||||
public ObservableCollection<EntryVm> History { get; private set; }
|
||||
public ObservableCollection<Field> AdditionalFields { get; private set; }
|
||||
public ObservableCollection<FieldVm> AdditionalFields { get; private set; }
|
||||
public ObservableCollection<Attachment> Attachments { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -82,11 +84,9 @@ namespace ModernKeePass.ViewModels
|
||||
Set(() => SelectedItem, ref _selectedItem, value, true);
|
||||
if (value != null)
|
||||
{
|
||||
AdditionalFields = new ObservableCollection<Field>(SelectedItem.AdditionalFields.Select(f => new Field
|
||||
{
|
||||
Name = f.Key,
|
||||
Value = f.Value
|
||||
}));
|
||||
AdditionalFields =
|
||||
new ObservableCollection<FieldVm>(
|
||||
SelectedItem.AdditionalFields.Select(f => new FieldVm(f.Key, f.Value)));
|
||||
Attachments = new ObservableCollection<Attachment>(SelectedItem.Attachments.Select(f => new Attachment
|
||||
{
|
||||
Name = f.Key,
|
||||
@@ -113,6 +113,16 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public int AdditionalFieldSelectedIndex
|
||||
{
|
||||
get { return _additionalFieldSelectedIndex; }
|
||||
set
|
||||
{
|
||||
Set(() => AdditionalFieldSelectedIndex, ref _additionalFieldSelectedIndex, value);
|
||||
DeleteAdditionalField.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public double PasswordLength
|
||||
{
|
||||
get { return _passwordLength; }
|
||||
@@ -258,6 +268,8 @@ namespace ModernKeePass.ViewModels
|
||||
public RelayCommand DeleteCommand { get; }
|
||||
public RelayCommand GoBackCommand { get; }
|
||||
public RelayCommand GoToParentCommand { get; set; }
|
||||
public RelayCommand AddAdditionalField { get; set; }
|
||||
public RelayCommand<FieldVm> DeleteAdditionalField { get; set; }
|
||||
public RelayCommand<Attachment> OpenAttachmentCommand { get; set; }
|
||||
public RelayCommand AddAttachmentCommand { get; set; }
|
||||
public RelayCommand<Attachment> DeleteAttachmentCommand { get; set; }
|
||||
@@ -273,6 +285,7 @@ namespace ModernKeePass.ViewModels
|
||||
private GroupVm _parent;
|
||||
private EntryVm _selectedItem;
|
||||
private int _selectedIndex;
|
||||
private int _additionalFieldSelectedIndex;
|
||||
private bool _isEditMode;
|
||||
private bool _isRevealPassword;
|
||||
private double _passwordLength = 25;
|
||||
@@ -294,11 +307,15 @@ namespace ModernKeePass.ViewModels
|
||||
DeleteCommand = new RelayCommand(async () => await AskForDelete());
|
||||
GoBackCommand = new RelayCommand(() => _navigation.GoBack());
|
||||
GoToParentCommand = new RelayCommand(() => GoToGroup(_parent.Id));
|
||||
AddAdditionalField = new RelayCommand(AddField);
|
||||
DeleteAdditionalField = new RelayCommand<FieldVm>(async field => await DeleteField(field), field => field != null);
|
||||
OpenAttachmentCommand = new RelayCommand<Attachment>(async attachment => await OpenAttachment(attachment));
|
||||
AddAttachmentCommand = new RelayCommand(async () => await AddAttachment(), () => IsCurrentEntry);
|
||||
DeleteAttachmentCommand = new RelayCommand<Attachment>(async attachment => await DeleteAttachment(attachment));
|
||||
|
||||
MessengerInstance.Register<DatabaseSavedMessage>(this, _ => SaveCommand.RaiseCanExecuteChanged());
|
||||
MessengerInstance.Register<EntryFieldValueChangedMessage>(this, async message => await SetFieldValue(message.FieldName, message.FieldValue));
|
||||
MessengerInstance.Register<EntryFieldNameChangedMessage>(this, async message => await UpdateFieldName(message.OldName, message.NewName, message.Value));
|
||||
}
|
||||
|
||||
public async Task Initialize(string entryId)
|
||||
@@ -314,6 +331,70 @@ namespace ModernKeePass.ViewModels
|
||||
History.CollectionChanged += (sender, args) => SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
public async Task GeneratePassword()
|
||||
{
|
||||
Password = await _mediator.Send(new GeneratePasswordCommand
|
||||
{
|
||||
BracketsPatternSelected = BracketsPatternSelected,
|
||||
CustomChars = CustomChars,
|
||||
DigitsPatternSelected = DigitsPatternSelected,
|
||||
LowerCasePatternSelected = LowerCasePatternSelected,
|
||||
MinusPatternSelected = MinusPatternSelected,
|
||||
PasswordLength = (int)PasswordLength,
|
||||
SpacePatternSelected = SpacePatternSelected,
|
||||
SpecialPatternSelected = SpecialPatternSelected,
|
||||
UnderscorePatternSelected = UnderscorePatternSelected,
|
||||
UpperCasePatternSelected = UpperCasePatternSelected
|
||||
});
|
||||
RaisePropertyChanged(nameof(IsRevealPasswordEnabled));
|
||||
}
|
||||
public async Task AddHistory()
|
||||
{
|
||||
if (_isDirty) await _mediator.Send(new AddHistoryCommand { Entry = History[0] });
|
||||
}
|
||||
|
||||
public void GoToGroup(string groupId)
|
||||
{
|
||||
_navigation.NavigateTo(Constants.Navigation.GroupPage, new NavigationItem { Id = groupId });
|
||||
}
|
||||
|
||||
private async Task Move(string destination)
|
||||
{
|
||||
await _mediator.Send(new AddEntryCommand { ParentGroupId = destination, EntryId = Id });
|
||||
await _mediator.Send(new RemoveEntryCommand { ParentGroupId = _parent.Id, EntryId = Id });
|
||||
GoToGroup(destination);
|
||||
}
|
||||
|
||||
private async Task SetFieldValue(string fieldName, object value)
|
||||
{
|
||||
await _mediator.Send(new UpsertFieldCommand { EntryId = Id, FieldName = fieldName, FieldValue = value });
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
private async Task UpdateFieldName(string oldName, string newName, string value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(oldName)) await _mediator.Send(new DeleteFieldCommand { EntryId = Id, FieldName = oldName });
|
||||
await SetFieldValue(newName, value);
|
||||
}
|
||||
|
||||
private void AddField()
|
||||
{
|
||||
AdditionalFields.Add(new FieldVm(string.Empty, string.Empty));
|
||||
AdditionalFieldSelectedIndex = AdditionalFields.Count - 1;
|
||||
}
|
||||
|
||||
private async Task DeleteField(FieldVm field)
|
||||
{
|
||||
AdditionalFields.Remove(field);
|
||||
if (!string.IsNullOrEmpty(field.Name))
|
||||
{
|
||||
await _mediator.Send(new DeleteFieldCommand {EntryId = Id, FieldName = field.Name});
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
_isDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AskForDelete()
|
||||
{
|
||||
if (IsCurrentEntry)
|
||||
@@ -349,48 +430,6 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public async Task GeneratePassword()
|
||||
{
|
||||
Password = await _mediator.Send(new GeneratePasswordCommand
|
||||
{
|
||||
BracketsPatternSelected = BracketsPatternSelected,
|
||||
CustomChars = CustomChars,
|
||||
DigitsPatternSelected = DigitsPatternSelected,
|
||||
LowerCasePatternSelected = LowerCasePatternSelected,
|
||||
MinusPatternSelected = MinusPatternSelected,
|
||||
PasswordLength = (int)PasswordLength,
|
||||
SpacePatternSelected = SpacePatternSelected,
|
||||
SpecialPatternSelected = SpecialPatternSelected,
|
||||
UnderscorePatternSelected = UnderscorePatternSelected,
|
||||
UpperCasePatternSelected = UpperCasePatternSelected
|
||||
});
|
||||
RaisePropertyChanged(nameof(IsRevealPasswordEnabled));
|
||||
}
|
||||
|
||||
public async Task Move(string destination)
|
||||
{
|
||||
await _mediator.Send(new AddEntryCommand { ParentGroupId = destination, EntryId = Id });
|
||||
await _mediator.Send(new RemoveEntryCommand { ParentGroupId = _parent.Id, EntryId = Id });
|
||||
GoToGroup(destination);
|
||||
}
|
||||
|
||||
public async Task SetFieldValue(string fieldName, object value)
|
||||
{
|
||||
await _mediator.Send(new SetFieldValueCommand { EntryId = Id, FieldName = fieldName, FieldValue = value });
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
public async Task AddHistory()
|
||||
{
|
||||
if (_isDirty) await _mediator.Send(new AddHistoryCommand { Entry = History[0] });
|
||||
}
|
||||
|
||||
public void GoToGroup(string groupId)
|
||||
{
|
||||
_navigation.NavigateTo(Constants.Navigation.GroupPage, new NavigationItem { Id = groupId });
|
||||
}
|
||||
|
||||
private async Task RestoreHistory()
|
||||
{
|
||||
await _mediator.Send(new RestoreHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex - 1 });
|
||||
@@ -442,12 +481,16 @@ namespace ModernKeePass.ViewModels
|
||||
var contents = await _file.ReadBinaryFile(fileInfo.Id);
|
||||
await _mediator.Send(new AddAttachmentCommand { Entry = SelectedItem, AttachmentName = fileInfo.Name, AttachmentContent = contents });
|
||||
Attachments.Add(new Attachment { Name = fileInfo.Name, Content = contents });
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
private async Task DeleteAttachment(Attachment attachment)
|
||||
{
|
||||
await _mediator.Send(new DeleteAttachmentCommand { Entry = SelectedItem, AttachmentName = attachment.Name });
|
||||
Attachments.Remove(attachment);
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -482,29 +482,40 @@
|
||||
</HubSection>
|
||||
<HubSection x:Uid="EntryHubAdditional">
|
||||
<DataTemplate>
|
||||
<local:SelectableTemplateListView
|
||||
ItemsSource="{Binding AdditionalFields}"
|
||||
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
|
||||
<local:SelectableTemplateListView.SelectedItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBox Text="{Binding Name, Mode=TwoWay}" Width="350"
|
||||
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
||||
<TextBox HorizontalAlignment="Left" AcceptsReturn="True" Height="100" TextWrapping="Wrap" Width="350"
|
||||
Text="{Binding Value, Mode=TwoWay}"
|
||||
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</local:SelectableTemplateListView.SelectedItemTemplate>
|
||||
<local:SelectableTemplateListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Text="{Binding Name}" Style="{StaticResource EntryTextBlockStyle}" FontWeight="SemiBold" />
|
||||
<TextBlock HorizontalAlignment="Left" MaxLines="3" FontSize="12" Margin="2,0,2,5" Text="{Binding Value}" Style="{StaticResource EntryTextBlockStyle}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</local:SelectableTemplateListView.ItemTemplate>
|
||||
</local:SelectableTemplateListView>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<HyperlinkButton Command="{Binding Path=DataContext.AddAdditionalField, ElementName=Page}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<SymbolIcon Symbol="Add" />
|
||||
<TextBlock x:Uid="EntryAddAdditionalField" VerticalAlignment="Center" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
</HyperlinkButton>
|
||||
<Border BorderBrush="DarkGray" BorderThickness="0,0,0,1" />
|
||||
<local:SelectableTemplateListView
|
||||
ItemsSource="{Binding AdditionalFields}"
|
||||
SelectedIndex="{Binding AdditionalFieldSelectedIndex, Mode=TwoWay}"
|
||||
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
|
||||
<local:SelectableTemplateListView.SelectedItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBox Text="{Binding Name, Mode=TwoWay}" Width="350"
|
||||
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
||||
<TextBox HorizontalAlignment="Left" AcceptsReturn="True" Height="100" TextWrapping="Wrap" Width="350"
|
||||
Text="{Binding Value, Mode=TwoWay}"
|
||||
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
||||
<Button x:Uid="EntryDeleteAdditionalField" HorizontalAlignment="Right" Command="{Binding Path=DataContext.DeleteAdditionalField, ElementName=Page}" CommandParameter="{Binding}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</local:SelectableTemplateListView.SelectedItemTemplate>
|
||||
<local:SelectableTemplateListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Text="{Binding Name}" Style="{StaticResource EntryTextBlockStyle}" FontWeight="SemiBold" />
|
||||
<TextBlock HorizontalAlignment="Left" MaxLines="3" FontSize="12" Margin="2,0,2,5" Text="{Binding Value}" Style="{StaticResource EntryTextBlockStyle}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</local:SelectableTemplateListView.ItemTemplate>
|
||||
</local:SelectableTemplateListView>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</HubSection>
|
||||
<HubSection x:Uid="EntryHubAttachments" Foreground="{StaticResource HubSectionBrush}">
|
||||
|
@@ -20,6 +20,7 @@
|
||||
</StackPanel>
|
||||
</HyperlinkButton>
|
||||
<controls:SelectableTemplateListView Grid.Row="1"
|
||||
SelectedIndex="{Binding SelectedIndex}"
|
||||
ItemsSource="{Binding RecentItems}"
|
||||
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
|
||||
<controls:SelectableTemplateListView.SelectedItemTemplate>
|
||||
|
@@ -19,9 +19,17 @@ namespace ModernKeePass.Controls
|
||||
|
||||
public SelectableTemplateListView()
|
||||
{
|
||||
ContainerContentChanging += SelectableTemplateListView_ContainerContentChanging;
|
||||
SelectionChanged += SelectableTemplateListView_SelectionChanged;
|
||||
}
|
||||
|
||||
private void SelectableTemplateListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
|
||||
{
|
||||
args.ItemContainer.ContentTemplate = args.ItemContainer.IsSelected
|
||||
? SelectedItemTemplate
|
||||
: ItemTemplate;
|
||||
}
|
||||
|
||||
private void SelectableTemplateListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
var listView = sender as ListView;
|
||||
|
9
WinAppCommon/Messages/EntryFieldNameChangedMessage.cs
Normal file
9
WinAppCommon/Messages/EntryFieldNameChangedMessage.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Messages
|
||||
{
|
||||
public class EntryFieldNameChangedMessage
|
||||
{
|
||||
public string OldName { get; set; }
|
||||
public string NewName { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
8
WinAppCommon/Messages/EntryFieldValueChangedMessage.cs
Normal file
8
WinAppCommon/Messages/EntryFieldValueChangedMessage.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Messages
|
||||
{
|
||||
public class EntryFieldValueChangedMessage
|
||||
{
|
||||
public string FieldName { get; set; }
|
||||
public string FieldValue { get; set; }
|
||||
}
|
||||
}
|
37
WinAppCommon/ViewModels/Items/FieldVm.cs
Normal file
37
WinAppCommon/ViewModels/Items/FieldVm.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using GalaSoft.MvvmLight;
|
||||
using Messages;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class FieldVm: ViewModelBase
|
||||
{
|
||||
private string _name;
|
||||
private string _value;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
MessengerInstance.Send(new EntryFieldNameChangedMessage { OldName = Name, NewName = value, Value = Value });
|
||||
Set(nameof(Name), ref _name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string Value
|
||||
{
|
||||
get { return _value; }
|
||||
set
|
||||
{
|
||||
MessengerInstance.Send(new EntryFieldValueChangedMessage { FieldName = Name, FieldValue = value });
|
||||
Set(nameof(Value), ref _value, value);
|
||||
}
|
||||
}
|
||||
|
||||
public FieldVm(string fieldName, string fieldValue)
|
||||
{
|
||||
_name = fieldName;
|
||||
_value = fieldValue;
|
||||
}
|
||||
}
|
||||
}
|
@@ -13,6 +13,7 @@ namespace ModernKeePass.ViewModels
|
||||
{
|
||||
private readonly IRecentProxy _recent;
|
||||
private ObservableCollection<RecentItemVm> _recentItems;
|
||||
private int _selectedIndex;
|
||||
|
||||
public ObservableCollection<RecentItemVm> RecentItems
|
||||
{
|
||||
@@ -22,6 +23,12 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public ICommand ClearAllCommand { get; }
|
||||
|
||||
public int SelectedIndex
|
||||
{
|
||||
get { return _selectedIndex; }
|
||||
set { Set(() => SelectedIndex, ref _selectedIndex, value); }
|
||||
}
|
||||
|
||||
public RecentVm(IRecentProxy recent)
|
||||
{
|
||||
_recent = recent;
|
||||
@@ -34,6 +41,7 @@ namespace ModernKeePass.ViewModels
|
||||
{
|
||||
var recentItems = _recent.GetAll().Select(r => new RecentItemVm(r));
|
||||
RecentItems = new ObservableCollection<RecentItemVm>(recentItems);
|
||||
if (RecentItems.Any()) SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private void ClearAll()
|
||||
|
@@ -36,10 +36,13 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseOpenedMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseOpeningMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseSavedMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\EntryFieldNameChangedMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\EntryFieldValueChangedMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\FileNotFoundMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\NavigateToPageMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\SaveErrorMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\AboutVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\FieldVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\ViewModelLocatorCommon.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\ListMenuItemVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\MainMenuItemVm.cs" />
|
||||
|
Reference in New Issue
Block a user