From 7917d2fbc09cc78de45ee4dbb3542a4595366c65 Mon Sep 17 00:00:00 2001 From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com> Date: Thu, 2 Feb 2023 20:40:32 +0600 Subject: [PATCH 01/26] Added NewAutoSuggestBox --- .../AutoSuggestBox/NewAutoSuggestBox.cs | 126 ++++++++++++ .../Styles/Controls/NewAutoSuggestBox.xaml | 183 ++++++++++++++++++ src/Wpf.Ui/Styles/Wpf.Ui.xaml | 1 + 3 files changed, 310 insertions(+) create mode 100644 src/Wpf.Ui/Controls/AutoSuggestBox/NewAutoSuggestBox.cs create mode 100644 src/Wpf.Ui/Styles/Controls/NewAutoSuggestBox.xaml diff --git a/src/Wpf.Ui/Controls/AutoSuggestBox/NewAutoSuggestBox.cs b/src/Wpf.Ui/Controls/AutoSuggestBox/NewAutoSuggestBox.cs new file mode 100644 index 000000000..0ab28ad70 --- /dev/null +++ b/src/Wpf.Ui/Controls/AutoSuggestBox/NewAutoSuggestBox.cs @@ -0,0 +1,126 @@ +using System.Windows; +using System; +using System.Diagnostics; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Input; + +namespace Wpf.Ui.Controls; + +[TemplatePart(Name = ElementTextBox, Type = typeof(System.Windows.Controls.TextBox))] +[TemplatePart(Name = ElementSuggestionsPopup, Type = typeof(System.Windows.Controls.Primitives.Popup))] +[TemplatePart(Name = ElementSuggestionsList, Type = typeof(System.Windows.Controls.ListView))] +public class NewAutoSuggestBox : System.Windows.Controls.ItemsControl +{ + protected const string ElementTextBox = "PART_TextBox"; + protected const string ElementSuggestionsPopup = "PART_SuggestionsPopup"; + protected const string ElementSuggestionsList = "PART_SuggestionsList"; + + #region Static properties + + /// + /// Property for . + /// + public static readonly DependencyProperty IsSuggestionListOpenProperty = DependencyProperty.Register(nameof(IsSuggestionListOpen), + typeof(bool), typeof(NewAutoSuggestBox), + new PropertyMetadata(false)); + + #endregion + + #region Properties + + /// + /// Gets or sets a Boolean value indicating whether the drop-down portion of the is open. + /// + public bool IsSuggestionListOpen + { + get => (bool)GetValue(IsSuggestionListOpenProperty); + set => SetValue(IsSuggestionListOpenProperty, value); + } + + #endregion + + protected System.Windows.Controls.TextBox TextBox = null!; + protected Popup SuggestionsPopup = null!; + protected ListView SuggestionsList = null!; + + public NewAutoSuggestBox() + { + Unloaded += static (sender, _) => + { + var self = (NewAutoSuggestBox)sender; + + self.ReleaseTemplateResources(); + }; + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + TextBox = GetTemplateChild(ElementTextBox); + SuggestionsPopup = GetTemplateChild(ElementSuggestionsPopup); + SuggestionsList = GetTemplateChild(ElementSuggestionsList); + + TextBox.PreviewKeyDown += TextBoxOnPreviewKeyDown; + TextBox.TextChanged += TextBoxOnTextChanged; + + SuggestionsList.SelectionChanged += SuggestionsListOnSelectionChanged; + SuggestionsList.PreviewKeyDown += SuggestionsListOnPreviewKeyDown; + SuggestionsList.LostKeyboardFocus += SuggestionsListOnLostKeyboardFocus; + } + + protected T GetTemplateChild(string name) where T : DependencyObject + { + if (GetTemplateChild(name) is not T dependencyObject) + throw new ArgumentNullException(name); + + return dependencyObject; + } + + protected virtual void ReleaseTemplateResources() + { + TextBox.PreviewKeyDown -= TextBoxOnPreviewKeyDown; + TextBox.TextChanged -= TextBoxOnTextChanged; + + SuggestionsList.SelectionChanged -= SuggestionsListOnSelectionChanged; + SuggestionsList.PreviewKeyDown -= SuggestionsListOnPreviewKeyDown; + SuggestionsList.LostKeyboardFocus -= SuggestionsListOnLostKeyboardFocus; + } + + private void TextBoxOnPreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key is not Key.Down || !IsSuggestionListOpen) + return; + + SuggestionsList.Focus(); + } + + private void SuggestionsListOnLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) + { + Debug.WriteLine("Losing focus"); + + if (e.NewFocus is ListViewItem) + return; + + IsSuggestionListOpen = false; + } + + private void TextBoxOnTextChanged(object sender, TextChangedEventArgs e) + { + IsSuggestionListOpen = true; + } + + private void SuggestionsListOnPreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key is not Key.Enter) + return; + + var q = SuggestionsList.SelectedItem; + } + + private void SuggestionsListOnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + Debug.WriteLine($"Selected | {e.AddedItems[0]}"); + } +} diff --git a/src/Wpf.Ui/Styles/Controls/NewAutoSuggestBox.xaml b/src/Wpf.Ui/Styles/Controls/NewAutoSuggestBox.xaml new file mode 100644 index 000000000..2c857352b --- /dev/null +++ b/src/Wpf.Ui/Styles/Controls/NewAutoSuggestBox.xaml @@ -0,0 +1,183 @@ + + + 1,1,1,0 + 0,0,0,1 + 10,8,0,0 + 0,8,10,0 + 0,5,4,0 + 0,0,0,0 + 24 + 14 + + + + + + - - - - - - - - - -