diff --git a/UI/Controls/SearchPane.axaml b/UI/Controls/SearchPane.axaml index efbf0c1..6dbdebe 100644 --- a/UI/Controls/SearchPane.axaml +++ b/UI/Controls/SearchPane.axaml @@ -4,40 +4,31 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:assets="clr-namespace:TagHierarchyManager.UI.Assets" xmlns:vm="clr-namespace:TagHierarchyManager.UI.ViewModels" - xmlns:parameterConverters="clr-namespace:TagHierarchyManager.UI.ParameterConverters" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="TagHierarchyManager.UI.Views.Controls.SearchPane" x:DataType="vm:SearchViewModel"> - - - + Content="{x:Static assets:Resources.SearchEnableAliases}" + IsChecked="{Binding SearchAliases}"/> - - - - - - + values, Type targetType, object? parameter, CultureInfo culture) - { - return values.ToArray(); - } -} \ No newline at end of file diff --git a/UI/ViewModels/SearchViewModel.cs b/UI/ViewModels/SearchViewModel.cs index 376fad9..71b4d8b 100644 --- a/UI/ViewModels/SearchViewModel.cs +++ b/UI/ViewModels/SearchViewModel.cs @@ -11,10 +11,15 @@ namespace TagHierarchyManager.UI.ViewModels; public partial class SearchViewModel : ViewModelBase, IDisposable { - private readonly MainWindowViewModel _mainWindow; private readonly Func, List> _getParentNamesById; + private readonly MainWindowViewModel _mainWindow; + [ObservableProperty] private bool _searchAliases; + [ObservableProperty] private TagDatabaseSearchMode _searchMode = TagDatabaseSearchMode.Fuzzy; + + [ObservableProperty] private string _searchQuery = string.Empty; [ObservableProperty] private ObservableCollection _searchResults = []; + [ObservableProperty] private SearchModeOption _selectedSearchMode; [ObservableProperty] private TagItemViewModel? _selectedSearchResult; @@ -23,8 +28,17 @@ public partial class SearchViewModel : ViewModelBase, IDisposable this._mainWindow = mainWindow; this._getParentNamesById = this._mainWindow.GetParentNamesById; mainWindow.TagDatabaseService.TagsWritten += this.TagDatabase_OnTagsWritten; + this._selectedSearchMode = this.SearchModes.First(); } + public IReadOnlyList SearchModes { get; } = + [ + new(TagDatabaseSearchMode.Fuzzy, Resources.SearchModeFuzzy), + new(TagDatabaseSearchMode.StartsWith, Resources.SearchModeStartsWith), + new(TagDatabaseSearchMode.EndsWith, Resources.SearchModeEndsWith), + new(TagDatabaseSearchMode.ExactMatch, Resources.SearchModeExactMatch) + ]; + public void Dispose() { this._mainWindow.TagDatabaseService.TagsWritten -= this.TagDatabase_OnTagsWritten; @@ -36,45 +50,32 @@ public partial class SearchViewModel : ViewModelBase, IDisposable this._mainWindow.SelectedTag = value; } - private void Search(string searchQuery, TagDatabaseSearchMode mode, bool searchAliases) - { - if (!this._mainWindow.TagDatabaseService.IsDatabaseOpen || string.IsNullOrWhiteSpace(searchQuery)) return; - - this.SearchResults.Clear(); - - var results = this._mainWindow.TagDatabaseService.SearchTags(searchQuery, mode, searchAliases); - - if (results.Count == 0) - { - this._mainWindow.StatusBlockText = Resources.SearchNoResultsFound; - return; - } - - results.Select(tag => - new TagItemViewModel(tag, this._getParentNamesById)) - .OrderBy(tag => tag.CurrentName) - .ToList() - .ForEach(this.SearchResults.Add); - - this._mainWindow.StatusBlockText = results.Count > 1 - ? string.Format(Resources.SearchMultipleResultsFound, results.Count) - : Resources.SearchOneResultFound; - } - - [RelayCommand] - private void StartSearch(object? parameter) + private void Search() { - if (parameter is not object[] values || values.Length < 3) return; - - var query = values[0] as string ?? string.Empty; - if (string.IsNullOrWhiteSpace(query)) return; - var mode = (TagDatabaseSearchMode)values[1]; - var searchAliases = (bool)values[2]; - + if (!this._mainWindow.TagDatabaseService.IsDatabaseOpen || string.IsNullOrWhiteSpace(this.SearchQuery)) return; try { - this.Search(query, mode, searchAliases); + this.SearchResults.Clear(); + + var results = this._mainWindow.TagDatabaseService.SearchTags( + this.SearchQuery, this.SelectedSearchMode.Mode, this.SearchAliases); + + if (results.Count == 0) + { + this._mainWindow.StatusBlockText = Resources.SearchNoResultsFound; + return; + } + + results.Select(tag => + new TagItemViewModel(tag, this._getParentNamesById)) + .OrderBy(tag => tag.CurrentName) + .ToList() + .ForEach(this.SearchResults.Add); + + this._mainWindow.StatusBlockText = results.Count > 1 + ? string.Format(Resources.SearchMultipleResultsFound, results.Count) + : Resources.SearchOneResultFound; } catch (Exception ex) { @@ -94,4 +95,6 @@ public partial class SearchViewModel : ViewModelBase, IDisposable this.SearchResults.Remove(deletedTagItemVm); } } + + public sealed record SearchModeOption(TagDatabaseSearchMode Mode, string DisplayName); } \ No newline at end of file