From b8f10e72d73634f1d924a4b31b821d6f0bbab8cc Mon Sep 17 00:00:00 2001 From: "kwan.nguyen" Date: Fri, 6 Dec 2024 02:09:21 +0700 Subject: [PATCH] update inputable dropdown --- PCUT/PCUT/Models/SelectableCollection.cs | 82 ++++++++++++++++++- PCUT/PCUT/Package.appxmanifest | 2 +- PCUT/PCUT/Pages/Logs/LogInformationPage.xaml | 5 +- .../Pages/Logs/LogInformationPage.xaml.cs | 2 +- PCUT/PCUT/ViewModels/LogViewModel.cs | 2 +- 5 files changed, 84 insertions(+), 9 deletions(-) diff --git a/PCUT/PCUT/Models/SelectableCollection.cs b/PCUT/PCUT/Models/SelectableCollection.cs index 4bb2afe..3863deb 100644 --- a/PCUT/PCUT/Models/SelectableCollection.cs +++ b/PCUT/PCUT/Models/SelectableCollection.cs @@ -1,11 +1,8 @@ using PCUT.Extensions; -using PCUT.Models; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; @@ -52,6 +49,19 @@ namespace PCUT.Models if (selector != null) selector.SelectionChanged += Selector_SelectionChanged; } + + public virtual void Bind(AutoSuggestBox autoSuggestBox, bool validateMemberPath = true) + { + if (validateMemberPath && string.IsNullOrEmpty(autoSuggestBox.TextMemberPath)) + throw new ArgumentException("Cannot bind auto suggestion box with default binding strategy. TextMemberPath is null"); + autoSuggestBox.TextChanged += AutoSuggestBoxTextChanged; + autoSuggestBox.SuggestionChosen += AutoSuggestBoxSuggestionChosen; + autoSuggestBox.QuerySubmitted += AutoSuggestBoxQuerySubmitted; + } + + protected virtual void AutoSuggestBoxTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) { } + protected virtual void AutoSuggestBoxSuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args) { } + protected virtual void AutoSuggestBoxQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args) { } } public class SelectableCollection : SelectableCollection @@ -62,6 +72,8 @@ namespace PCUT.Models public ObservableCollection Items { get; } public T SelectedItem => _selectedIndex >= 0 ? Items[_selectedIndex] : default; + private Func _propertySelector; + public SelectableCollection(T defaultItem) : base(true) { DefaultItem = defaultItem; @@ -127,6 +139,70 @@ namespace PCUT.Models { var start = _withDefault ? 1 : 0; Items.Filter(_items, filter, start); + _selectedIndex = -2; // set to -2 so that the next select will trigger property changed event + } + + public void Bind(AutoSuggestBox autoSuggestBox, Func propertySelector) + { + _propertySelector = propertySelector; + base.Bind(autoSuggestBox, validateMemberPath: propertySelector is null); + } + + protected override void AutoSuggestBoxTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) + { + if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput) + { + Predicate filter; + if (string.IsNullOrEmpty(sender.Text)) + { + filter = x => true; + } + else if (_propertySelector != null) + { + filter = x => _propertySelector.Invoke(x)?.StartsWith(sender.Text) ?? false; + } + else + { + var propertyInfo = typeof(T).GetProperty(sender.TextMemberPath, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); + filter = x => propertyInfo.GetValue(x)?.ToString()?.StartsWith(sender.Text) ?? false; + } + Filter(filter); + } + } + + protected override void AutoSuggestBoxSuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args) + { + + } + + protected override void AutoSuggestBoxQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args) + { + if (string.IsNullOrEmpty(args.QueryText)) + { + SelectedIndex = -1; + } + else if (args.ChosenSuggestion != null) + { + SelectedIndex = Items.IndexOf((T)args.ChosenSuggestion); + } + else + { + Func filter; + if (_propertySelector != null) + { + filter = x => _propertySelector.Invoke(x) == sender.Text; + } + else + { + var propertyInfo = typeof(T).GetProperty(sender.TextMemberPath, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); + filter = x => propertyInfo.GetValue(x)?.ToString() == sender.Text; + } + var item = Items.FirstOrDefault(filter); + if (item != null) + { + SelectedIndex = Items.IndexOf(item); + } + } } } } diff --git a/PCUT/PCUT/Package.appxmanifest b/PCUT/PCUT/Package.appxmanifest index 4e1b42e..a4d67d6 100644 --- a/PCUT/PCUT/Package.appxmanifest +++ b/PCUT/PCUT/Package.appxmanifest @@ -9,7 +9,7 @@ + Version="1.3.4.12" /> diff --git a/PCUT/PCUT/Pages/Logs/LogInformationPage.xaml b/PCUT/PCUT/Pages/Logs/LogInformationPage.xaml index e10750d..9739ef4 100644 --- a/PCUT/PCUT/Pages/Logs/LogInformationPage.xaml +++ b/PCUT/PCUT/Pages/Logs/LogInformationPage.xaml @@ -37,14 +37,13 @@ - user.UserName); await ViewModels.LoadUsersAsync(); } diff --git a/PCUT/PCUT/ViewModels/LogViewModel.cs b/PCUT/PCUT/ViewModels/LogViewModel.cs index 2db2409..f7edc1d 100644 --- a/PCUT/PCUT/ViewModels/LogViewModel.cs +++ b/PCUT/PCUT/ViewModels/LogViewModel.cs @@ -18,7 +18,7 @@ namespace PCUT.ViewModels public class LogViewModel : NotificationBase { public PaginationViewModel Pagination { get; } = new PaginationViewModel(withSearch: false); - public SelectableCollection Users { get; set; } = new SelectableCollection(new UsersModel { UserName = "-None-" }); + public SelectableCollection Users { get; set; } = new SelectableCollection(); public SelectableCollection Types { get; set; } = new SelectableCollection("-None-", new string[] { "login", "logout", "download", "cut" }); public ObservableCollection Logs { get; }