diff --git a/Core/TagHierarchyManager.csproj b/Core/TagHierarchyManager.csproj index 7799ac8..321722d 100644 --- a/Core/TagHierarchyManager.csproj +++ b/Core/TagHierarchyManager.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/Tests/TagHierarchyManager.Tests.csproj b/Tests/TagHierarchyManager.Tests.csproj index 6ff0f98..28ab951 100644 --- a/Tests/TagHierarchyManager.Tests.csproj +++ b/Tests/TagHierarchyManager.Tests.csproj @@ -9,12 +9,12 @@ - - - - + + + + - + diff --git a/UI/App.axaml b/UI/App.axaml index 4418df7..278df15 100644 --- a/UI/App.axaml +++ b/UI/App.axaml @@ -3,7 +3,6 @@ x:Class="TagHierarchyManager.UI.App" xmlns:local="using:TagHierarchyManager.UI" xmlns:semi="https://irihi.tech/semi" - xmlns:u-semi="https://irihi.tech/ursa/themes/semi" RequestedThemeVariant="Dark"> @@ -13,7 +12,6 @@ - \ No newline at end of file diff --git a/UI/App.axaml.cs b/UI/App.axaml.cs index 5763ef3..a97e068 100644 --- a/UI/App.axaml.cs +++ b/UI/App.axaml.cs @@ -25,7 +25,6 @@ public class App : Application { // Avoid duplicate validations from both Avalonia and the CommunityToolkit. // More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins - this.DisableAvaloniaDataAnnotationValidation(); this.DialogService = new DialogService(); this.TagDatabaseService = new TagDatabaseService(this.DialogService); @@ -38,14 +37,5 @@ public class App : Application base.OnFrameworkInitializationCompleted(); } - - private void DisableAvaloniaDataAnnotationValidation() - { - // Get an array of plugins to remove - var dataValidationPluginsToRemove = - BindingPlugins.DataValidators.OfType().ToArray(); - - // remove each entry found - foreach (var plugin in dataValidationPluginsToRemove) BindingPlugins.DataValidators.Remove(plugin); - } + } \ No newline at end of file diff --git a/UI/Controls/MultiValueAutoCompleteBox.axaml b/UI/Controls/MultiValueAutoCompleteBox.axaml index a8435f8..9e41b8f 100644 --- a/UI/Controls/MultiValueAutoCompleteBox.axaml +++ b/UI/Controls/MultiValueAutoCompleteBox.axaml @@ -12,7 +12,7 @@ RelativeSource={RelativeSource AncestorType=controls:MultiValueAutoCompleteBox}}" Watermark="{Binding Watermark, RelativeSource={RelativeSource AncestorType=controls:MultiValueAutoCompleteBox}}" - TextChanged="TextBox_OnTextChanged" KeyDown="TextBox_OnKeyDown" + TextChanged="TextBox_OnTextChanged" GotFocus="TextBox_OnGotFocus" LostFocus="TextBox_OnLostFocus" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> @@ -24,8 +24,7 @@ + PointerPressed="ListBox_OnPointerPressed"> @@ -37,4 +36,4 @@ - \ No newline at end of file + diff --git a/UI/Controls/MultiValueAutoCompleteBox.axaml.cs b/UI/Controls/MultiValueAutoCompleteBox.axaml.cs index 127a34c..67f6563 100644 --- a/UI/Controls/MultiValueAutoCompleteBox.axaml.cs +++ b/UI/Controls/MultiValueAutoCompleteBox.axaml.cs @@ -53,6 +53,10 @@ public partial class MultiValueAutoCompleteBox : UserControl .GetPropertyChangedObservable(BoundsProperty) .Subscribe(new AnonymousObserver(e => this.MultiValueAutoCompleteListBox.Width = ((Rect)e.NewValue!).Width)); + this.MultiValueAutoCompleteBoxTextBox.AddHandler(KeyDownEvent, TextBox_OnKeyDown, + RoutingStrategies.Bubble, handledEventsToo: true); + this.MultiValueAutoCompleteBoxTextBox.AddHandler(PointerPressedEvent, + ListBox_OnPointerPressed, RoutingStrategies.Tunnel, handledEventsToo: true); this.KeyDown += (_, e) => { @@ -158,18 +162,11 @@ public partial class MultiValueAutoCompleteBox : UserControl this._currentSegment = new SegmentData(activeSegment.Trim(), backIndex, forwardIndex, spaceAtBeginning); } - private void ListBox_OnKeyDown(object? sender, KeyEventArgs e) + private void ListBox_OnPointerPressed(object? sender, PointerPressedEventArgs e) { - if (sender is not ListBox { SelectedItem: TagItemViewModel tag } listBox) return; - - if (e.Key != Key.Enter) return; - this.ApplyListBoxSelection(listBox, tag); + if (sender is not ListBox listBox) return; + if (e.Source is not Control { DataContext: TagItemViewModel tag }) return; e.Handled = true; - } - - private void ListBox_OnPointerReleased(object? sender, PointerReleasedEventArgs e) - { - if (sender is not ListBox { SelectedItem: TagItemViewModel tag } listBox) return; this.ApplyListBoxSelection(listBox, tag); } @@ -180,6 +177,7 @@ public partial class MultiValueAutoCompleteBox : UserControl if (!string.IsNullOrWhiteSpace(itemName) && this.ItemsSource is not null) { var filtered = this.ItemsSource + .DistinctBy(t => t.CurrentName) .Where(t => t.CurrentName.Contains(itemName, StringComparison.OrdinalIgnoreCase)) .OrderBy(t => t.CurrentName, StringComparer.OrdinalIgnoreCase).ToList(); if (filtered.Count == 1 && filtered[0].CurrentName == this._currentSegment.FullSegment) return; @@ -190,19 +188,32 @@ public partial class MultiValueAutoCompleteBox : UserControl this.UpdatePopupIsVisible(); } - private void TextBox_OnGotFocus(object? sender, GotFocusEventArgs e) + private void TextBox_OnGotFocus(object? sender, FocusChangedEventArgs e) { this._isTextBoxActive = true; } private void TextBox_OnKeyDown(object? sender, KeyEventArgs e) { - if (e.Key != Key.Down) return; if (!this.MultiValueAutoCompletePopup.IsOpen) return; - this.MultiValueAutoCompleteListBox.SelectedIndex = 0; - var first = this.MultiValueAutoCompleteListBox.ContainerFromIndex(0); - first?.Focus(); - e.Handled = true; + var listBox = this.MultiValueAutoCompleteListBox; + switch (e.Key) + { + case Key.Down: + listBox.SelectedIndex = + Math.Min(listBox.SelectedIndex + 1, this.FilteredItems.Count - 1); + e.Handled = true; + break; + case Key.Up: + listBox.SelectedIndex = + Math.Max(listBox.SelectedIndex - 1, 0); + e.Handled = true; + break; + case Key.Enter when listBox.SelectedItem is TagItemViewModel tag: + this.ApplyListBoxSelection(listBox, tag); + e.Handled = true; + break; + } } private void TextBox_OnLostFocus(object? sender, RoutedEventArgs e) diff --git a/UI/TagHierarchyManager.UI.csproj b/UI/TagHierarchyManager.UI.csproj index 0f4955a..a7a795a 100644 --- a/UI/TagHierarchyManager.UI.csproj +++ b/UI/TagHierarchyManager.UI.csproj @@ -82,20 +82,18 @@ - - - - + + + + - + None All - - - - - + + +