Sicherung
This commit is contained in:
612
AutoCompleteTextBox/Editors/AutoCompleteComboBox.cs
Normal file
612
AutoCompleteTextBox/Editors/AutoCompleteComboBox.cs
Normal file
@@ -0,0 +1,612 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace AutoCompleteTextBox.Editors
|
||||
{
|
||||
[TemplatePart(Name = PartEditor, Type = typeof(TextBox))]
|
||||
[TemplatePart(Name = PartPopup, Type = typeof(Popup))]
|
||||
[TemplatePart(Name = PartSelector, Type = typeof(Selector))]
|
||||
[TemplatePart(Name = PartExpander, Type = typeof(Expander))]
|
||||
public class AutoCompleteComboBox : Control
|
||||
{
|
||||
|
||||
#region "Fields"
|
||||
|
||||
public const string PartEditor = "PART_Editor";
|
||||
public const string PartPopup = "PART_Popup";
|
||||
|
||||
public const string PartSelector = "PART_Selector";
|
||||
public const string PartExpander = "PART_Expander";
|
||||
public static readonly DependencyProperty DelayProperty = DependencyProperty.Register("Delay", typeof(int), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(200));
|
||||
public static readonly DependencyProperty DisplayMemberProperty = DependencyProperty.Register("DisplayMember", typeof(string), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(string.Empty));
|
||||
public static readonly DependencyProperty IconPlacementProperty = DependencyProperty.Register("IconPlacement", typeof(IconPlacement), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(IconPlacement.Left));
|
||||
public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(object), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(null));
|
||||
public static readonly DependencyProperty IconVisibilityProperty = DependencyProperty.Register("IconVisibility", typeof(Visibility), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(Visibility.Visible));
|
||||
public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(false));
|
||||
public static readonly DependencyProperty IsLoadingProperty = DependencyProperty.Register("IsLoading", typeof(bool), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(false));
|
||||
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(false));
|
||||
public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(null));
|
||||
public static readonly DependencyProperty ItemTemplateSelectorProperty = DependencyProperty.Register("ItemTemplateSelector", typeof(DataTemplateSelector), typeof(AutoCompleteComboBox));
|
||||
public static readonly DependencyProperty LoadingContentProperty = DependencyProperty.Register("LoadingContent", typeof(object), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(null));
|
||||
public static readonly DependencyProperty ProviderProperty = DependencyProperty.Register("Provider", typeof(IComboSuggestionProvider), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(null));
|
||||
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(null, OnSelectedItemChanged));
|
||||
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(string.Empty, propertyChangedCallback: null, coerceValueCallback: null, isAnimationProhibited: false, defaultUpdateSourceTrigger: UpdateSourceTrigger.LostFocus, flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
|
||||
public static readonly DependencyProperty FilterProperty = DependencyProperty.Register("Filter", typeof(string), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(string.Empty));
|
||||
public static readonly DependencyProperty MaxLengthProperty = DependencyProperty.Register("MaxLength", typeof(int), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(0));
|
||||
public static readonly DependencyProperty CharacterCasingProperty = DependencyProperty.Register("CharacterCasing", typeof(CharacterCasing), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(CharacterCasing.Normal));
|
||||
public static readonly DependencyProperty MaxPopUpHeightProperty = DependencyProperty.Register("MaxPopUpHeight", typeof(int), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(600));
|
||||
public static readonly DependencyProperty MaxPopUpWidthProperty = DependencyProperty.Register("MaxPopUpWidth", typeof(int), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(2000));
|
||||
|
||||
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(string), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(string.Empty));
|
||||
|
||||
public static readonly DependencyProperty SuggestionBackgroundProperty = DependencyProperty.Register("SuggestionBackground", typeof(Brush), typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(Brushes.White));
|
||||
private bool _isUpdatingText;
|
||||
private bool _selectionCancelled;
|
||||
|
||||
private SuggestionsAdapter _suggestionsAdapter;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region "Constructors"
|
||||
|
||||
static AutoCompleteComboBox()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(AutoCompleteComboBox), new FrameworkPropertyMetadata(typeof(AutoCompleteComboBox)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region "Properties"
|
||||
|
||||
|
||||
public int MaxPopupHeight
|
||||
{
|
||||
get => (int)GetValue(MaxPopUpHeightProperty);
|
||||
set => SetValue(MaxPopUpHeightProperty, value);
|
||||
}
|
||||
public int MaxPopupWidth
|
||||
{
|
||||
get => (int)GetValue(MaxPopUpWidthProperty);
|
||||
set => SetValue(MaxPopUpWidthProperty, value);
|
||||
}
|
||||
|
||||
|
||||
public BindingEvaluator BindingEvaluator { get; set; }
|
||||
|
||||
public CharacterCasing CharacterCasing
|
||||
{
|
||||
get => (CharacterCasing)GetValue(CharacterCasingProperty);
|
||||
set => SetValue(CharacterCasingProperty, value);
|
||||
}
|
||||
|
||||
public int MaxLength
|
||||
{
|
||||
get => (int)GetValue(MaxLengthProperty);
|
||||
set => SetValue(MaxLengthProperty, value);
|
||||
}
|
||||
|
||||
public int Delay
|
||||
{
|
||||
get => (int)GetValue(DelayProperty);
|
||||
|
||||
set => SetValue(DelayProperty, value);
|
||||
}
|
||||
|
||||
public string DisplayMember
|
||||
{
|
||||
get => (string)GetValue(DisplayMemberProperty);
|
||||
|
||||
set => SetValue(DisplayMemberProperty, value);
|
||||
}
|
||||
|
||||
public TextBox Editor { get; set; }
|
||||
public Expander Expander { get; set; }
|
||||
|
||||
public DispatcherTimer FetchTimer { get; set; }
|
||||
|
||||
public string Filter
|
||||
{
|
||||
get => (string)GetValue(FilterProperty);
|
||||
|
||||
set => SetValue(FilterProperty, value);
|
||||
}
|
||||
|
||||
public object Icon
|
||||
{
|
||||
get => GetValue(IconProperty);
|
||||
|
||||
set => SetValue(IconProperty, value);
|
||||
}
|
||||
|
||||
public IconPlacement IconPlacement
|
||||
{
|
||||
get => (IconPlacement)GetValue(IconPlacementProperty);
|
||||
|
||||
set => SetValue(IconPlacementProperty, value);
|
||||
}
|
||||
|
||||
public Visibility IconVisibility
|
||||
{
|
||||
get => (Visibility)GetValue(IconVisibilityProperty);
|
||||
|
||||
set => SetValue(IconVisibilityProperty, value);
|
||||
}
|
||||
|
||||
public bool IsDropDownOpen
|
||||
{
|
||||
get => (bool)GetValue(IsDropDownOpenProperty);
|
||||
|
||||
set
|
||||
{
|
||||
this.Expander.IsExpanded = value;
|
||||
SetValue(IsDropDownOpenProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsLoading
|
||||
{
|
||||
get => (bool)GetValue(IsLoadingProperty);
|
||||
|
||||
set => SetValue(IsLoadingProperty, value);
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get => (bool)GetValue(IsReadOnlyProperty);
|
||||
|
||||
set => SetValue(IsReadOnlyProperty, value);
|
||||
}
|
||||
|
||||
public Selector ItemsSelector { get; set; }
|
||||
|
||||
public DataTemplate ItemTemplate
|
||||
{
|
||||
get => (DataTemplate)GetValue(ItemTemplateProperty);
|
||||
|
||||
set => SetValue(ItemTemplateProperty, value);
|
||||
}
|
||||
|
||||
public DataTemplateSelector ItemTemplateSelector
|
||||
{
|
||||
get => ((DataTemplateSelector)(GetValue(ItemTemplateSelectorProperty)));
|
||||
set => SetValue(ItemTemplateSelectorProperty, value);
|
||||
}
|
||||
|
||||
public object LoadingContent
|
||||
{
|
||||
get => GetValue(LoadingContentProperty);
|
||||
|
||||
set => SetValue(LoadingContentProperty, value);
|
||||
}
|
||||
|
||||
public Popup Popup { get; set; }
|
||||
|
||||
public IComboSuggestionProvider Provider
|
||||
{
|
||||
get => (IComboSuggestionProvider)GetValue(ProviderProperty);
|
||||
|
||||
set => SetValue(ProviderProperty, value);
|
||||
}
|
||||
|
||||
public object SelectedItem
|
||||
{
|
||||
get => GetValue(SelectedItemProperty);
|
||||
|
||||
set => SetValue(SelectedItemProperty, value);
|
||||
}
|
||||
|
||||
public SelectionAdapter SelectionAdapter { get; set; }
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => (string)GetValue(TextProperty);
|
||||
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public string Watermark
|
||||
{
|
||||
get => (string)GetValue(WatermarkProperty);
|
||||
|
||||
set => SetValue(WatermarkProperty, value);
|
||||
}
|
||||
public Brush SuggestionBackground
|
||||
{
|
||||
get => (Brush)GetValue(SuggestionBackgroundProperty);
|
||||
|
||||
set => SetValue(SuggestionBackgroundProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region "Methods"
|
||||
|
||||
public static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
AutoCompleteComboBox act = null;
|
||||
act = d as AutoCompleteComboBox;
|
||||
if (act != null)
|
||||
{
|
||||
if (act.Editor != null & !act._isUpdatingText)
|
||||
{
|
||||
act._isUpdatingText = true;
|
||||
act.Editor.Text = act.BindingEvaluator.Evaluate(e.NewValue);
|
||||
act._isUpdatingText = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ScrollToSelectedItem()
|
||||
{
|
||||
if (ItemsSelector is ListBox listBox && listBox.SelectedItem != null)
|
||||
listBox.ScrollIntoView(listBox.SelectedItem);
|
||||
}
|
||||
|
||||
public new BindingExpressionBase SetBinding(DependencyProperty dp, BindingBase binding){
|
||||
var res = base.SetBinding(dp, binding);
|
||||
CheckForParentTextBindingChange();
|
||||
return res;
|
||||
}
|
||||
public new BindingExpressionBase SetBinding(DependencyProperty dp, String path) {
|
||||
var res = base.SetBinding(dp, path);
|
||||
CheckForParentTextBindingChange();
|
||||
return res;
|
||||
}
|
||||
public new void ClearValue(DependencyPropertyKey key) {
|
||||
base.ClearValue(key);
|
||||
CheckForParentTextBindingChange();
|
||||
}
|
||||
public new void ClearValue(DependencyProperty dp) {
|
||||
base.ClearValue(dp);
|
||||
CheckForParentTextBindingChange();
|
||||
}
|
||||
private void CheckForParentTextBindingChange(bool force=false) {
|
||||
var CurrentBindingMode = BindingOperations.GetBinding(this, TextProperty)?.UpdateSourceTrigger ?? UpdateSourceTrigger.Default;
|
||||
if (CurrentBindingMode != UpdateSourceTrigger.PropertyChanged)//preventing going any less frequent than property changed
|
||||
CurrentBindingMode = UpdateSourceTrigger.Default;
|
||||
|
||||
|
||||
if (CurrentBindingMode == CurrentTextboxTextBindingUpdateMode && force == false)
|
||||
return;
|
||||
var binding = new Binding {
|
||||
Mode = BindingMode.TwoWay,
|
||||
UpdateSourceTrigger = CurrentBindingMode,
|
||||
Path = new PropertyPath(nameof(Text)),
|
||||
RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent),
|
||||
};
|
||||
CurrentTextboxTextBindingUpdateMode = CurrentBindingMode;
|
||||
Editor?.SetBinding(TextBox.TextProperty, binding);
|
||||
}
|
||||
|
||||
private UpdateSourceTrigger CurrentTextboxTextBindingUpdateMode;
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
Editor = Template.FindName(PartEditor, this) as TextBox;
|
||||
Popup = Template.FindName(PartPopup, this) as Popup;
|
||||
ItemsSelector = Template.FindName(PartSelector, this) as Selector;
|
||||
Expander = Template.FindName(PartExpander, this) as Expander;
|
||||
|
||||
BindingEvaluator = new BindingEvaluator(new Binding(DisplayMember));
|
||||
|
||||
if (Editor != null)
|
||||
{
|
||||
Editor.TextChanged += OnEditorTextChanged;
|
||||
Editor.PreviewKeyDown += OnEditorKeyDown;
|
||||
Editor.LostFocus += OnEditorLostFocus;
|
||||
CheckForParentTextBindingChange(true);
|
||||
|
||||
if (SelectedItem != null)
|
||||
{
|
||||
_isUpdatingText = true;
|
||||
Editor.Text = BindingEvaluator.Evaluate(SelectedItem);
|
||||
_isUpdatingText = false;
|
||||
}
|
||||
|
||||
}
|
||||
if (Expander != null)
|
||||
{
|
||||
Expander.IsExpanded = false;
|
||||
Expander.Collapsed += Expander_Expanded;
|
||||
Expander.Expanded += Expander_Expanded;
|
||||
}
|
||||
|
||||
GotFocus += AutoCompleteComboBox_GotFocus;
|
||||
|
||||
if (Popup != null)
|
||||
{
|
||||
Popup.StaysOpen = false;
|
||||
Popup.Opened += OnPopupOpened;
|
||||
Popup.Closed += OnPopupClosed;
|
||||
}
|
||||
if (ItemsSelector != null)
|
||||
{
|
||||
SelectionAdapter = new SelectionAdapter(ItemsSelector);
|
||||
SelectionAdapter.Commit += OnSelectionAdapterCommit;
|
||||
SelectionAdapter.Cancel += OnSelectionAdapterCancel;
|
||||
SelectionAdapter.SelectionChanged += OnSelectionAdapterSelectionChanged;
|
||||
ItemsSelector.PreviewMouseDown += ItemsSelector_PreviewMouseDown;
|
||||
}
|
||||
}
|
||||
|
||||
private void Expander_Expanded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.IsDropDownOpen = Expander.IsExpanded;
|
||||
if (!this.IsDropDownOpen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_suggestionsAdapter == null)
|
||||
{
|
||||
_suggestionsAdapter = new SuggestionsAdapter(this);
|
||||
}
|
||||
if (SelectedItem != null || String.IsNullOrWhiteSpace(Editor.Text))
|
||||
_suggestionsAdapter.ShowFullCollection();
|
||||
|
||||
}
|
||||
|
||||
private void ItemsSelector_PreviewMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if ((e.OriginalSource as FrameworkElement)?.DataContext == null)
|
||||
return;
|
||||
if (!ItemsSelector.Items.Contains(((FrameworkElement)e.OriginalSource)?.DataContext))
|
||||
return;
|
||||
ItemsSelector.SelectedItem = ((FrameworkElement)e.OriginalSource)?.DataContext;
|
||||
OnSelectionAdapterCommit(SelectionAdapter.EventCause.ItemClicked);
|
||||
e.Handled = true;
|
||||
}
|
||||
private void AutoCompleteComboBox_GotFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Editor?.Focus();
|
||||
}
|
||||
|
||||
private string GetDisplayText(object dataItem)
|
||||
{
|
||||
if (BindingEvaluator == null)
|
||||
{
|
||||
BindingEvaluator = new BindingEvaluator(new Binding(DisplayMember));
|
||||
}
|
||||
if (dataItem == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
if (string.IsNullOrEmpty(DisplayMember))
|
||||
{
|
||||
return dataItem.ToString();
|
||||
}
|
||||
return BindingEvaluator.Evaluate(dataItem);
|
||||
}
|
||||
|
||||
private void OnEditorKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (SelectionAdapter != null)
|
||||
{
|
||||
if (IsDropDownOpen)
|
||||
SelectionAdapter.HandleKeyDown(e);
|
||||
else
|
||||
IsDropDownOpen = e.Key == Key.Down || e.Key == Key.Up;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEditorLostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!IsKeyboardFocusWithin)
|
||||
{
|
||||
IsDropDownOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEditorTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
Text = Editor.Text;
|
||||
if (_isUpdatingText)
|
||||
return;
|
||||
if (FetchTimer == null)
|
||||
{
|
||||
FetchTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(Delay) };
|
||||
FetchTimer.Tick += OnFetchTimerTick;
|
||||
}
|
||||
FetchTimer.IsEnabled = false;
|
||||
FetchTimer.Stop();
|
||||
SetSelectedItem(null);
|
||||
if (Editor.Text.Length > 0)
|
||||
{
|
||||
FetchTimer.IsEnabled = true;
|
||||
FetchTimer.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
IsDropDownOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFetchTimerTick(object sender, EventArgs e)
|
||||
{
|
||||
FetchTimer.IsEnabled = false;
|
||||
FetchTimer.Stop();
|
||||
if (Provider != null && ItemsSelector != null)
|
||||
{
|
||||
Filter = Editor.Text;
|
||||
if (_suggestionsAdapter == null)
|
||||
{
|
||||
_suggestionsAdapter = new SuggestionsAdapter(this);
|
||||
}
|
||||
_suggestionsAdapter.GetSuggestions(Filter);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPopupClosed(object sender, EventArgs e)
|
||||
{
|
||||
if (!_selectionCancelled)
|
||||
{
|
||||
OnSelectionAdapterCommit(SelectionAdapter.EventCause.PopupClosed);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPopupOpened(object sender, EventArgs e)
|
||||
{
|
||||
_selectionCancelled = false;
|
||||
ItemsSelector.SelectedItem = SelectedItem;
|
||||
}
|
||||
|
||||
public event EventHandler<SelectionAdapter.PreSelectionAdapterFinishArgs> PreSelectionAdapterFinish;
|
||||
private bool PreSelectionEventSomeoneHandled(SelectionAdapter.EventCause cause, bool is_cancel) {
|
||||
if (PreSelectionAdapterFinish == null)
|
||||
return false;
|
||||
var args = new SelectionAdapter.PreSelectionAdapterFinishArgs { cause = cause, is_cancel = is_cancel };
|
||||
PreSelectionAdapterFinish?.Invoke(this, args);
|
||||
return args.handled;
|
||||
|
||||
}
|
||||
private void OnSelectionAdapterCancel(SelectionAdapter.EventCause cause)
|
||||
{
|
||||
if (PreSelectionEventSomeoneHandled(cause, true))
|
||||
return;
|
||||
_isUpdatingText = true;
|
||||
Editor.Text = SelectedItem == null ? Filter : GetDisplayText(SelectedItem);
|
||||
Editor.SelectionStart = Editor.Text.Length;
|
||||
Editor.SelectionLength = 0;
|
||||
_isUpdatingText = false;
|
||||
IsDropDownOpen = false;
|
||||
_selectionCancelled = true;
|
||||
}
|
||||
|
||||
private void OnSelectionAdapterCommit(SelectionAdapter.EventCause cause)
|
||||
{
|
||||
if (PreSelectionEventSomeoneHandled(cause, false))
|
||||
return;
|
||||
|
||||
if (ItemsSelector.SelectedItem != null)
|
||||
{
|
||||
SelectedItem = ItemsSelector.SelectedItem;
|
||||
_isUpdatingText = true;
|
||||
Editor.Text = GetDisplayText(ItemsSelector.SelectedItem);
|
||||
SetSelectedItem(ItemsSelector.SelectedItem);
|
||||
_isUpdatingText = false;
|
||||
IsDropDownOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectionAdapterSelectionChanged()
|
||||
{
|
||||
_isUpdatingText = true;
|
||||
Editor.Text = ItemsSelector.SelectedItem == null ? Filter : GetDisplayText(ItemsSelector.SelectedItem);
|
||||
Editor.SelectionStart = Editor.Text.Length;
|
||||
Editor.SelectionLength = 0;
|
||||
ScrollToSelectedItem();
|
||||
_isUpdatingText = false;
|
||||
}
|
||||
|
||||
private void SetSelectedItem(object item)
|
||||
{
|
||||
_isUpdatingText = true;
|
||||
SelectedItem = item;
|
||||
_isUpdatingText = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "Nested Types"
|
||||
|
||||
private class SuggestionsAdapter
|
||||
{
|
||||
|
||||
#region "Fields"
|
||||
|
||||
private readonly AutoCompleteComboBox _actb;
|
||||
|
||||
private string _filter;
|
||||
#endregion
|
||||
|
||||
#region "Constructors"
|
||||
|
||||
public SuggestionsAdapter(AutoCompleteComboBox actb)
|
||||
{
|
||||
_actb = actb;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region "Methods"
|
||||
|
||||
public void GetSuggestions(string searchText)
|
||||
{
|
||||
_actb.IsLoading = true;
|
||||
// Do not open drop down if control is not focused
|
||||
if (_actb.IsKeyboardFocusWithin)
|
||||
_actb.IsDropDownOpen = true;
|
||||
_actb.ItemsSelector.ItemsSource = null;
|
||||
ParameterizedThreadStart thInfo = GetSuggestionsAsync;
|
||||
Thread th = new Thread(thInfo);
|
||||
_filter = searchText;
|
||||
th.Start(new object[] { searchText, _actb.Provider });
|
||||
}
|
||||
public void ShowFullCollection()
|
||||
{
|
||||
_filter = string.Empty;
|
||||
_actb.IsLoading = true;
|
||||
// Do not open drop down if control is not focused
|
||||
if (_actb.IsKeyboardFocusWithin)
|
||||
_actb.IsDropDownOpen = true;
|
||||
_actb.ItemsSelector.ItemsSource = null;
|
||||
ParameterizedThreadStart thInfo = GetFullCollectionAsync;
|
||||
Thread th = new Thread(thInfo);
|
||||
th.Start(_actb.Provider);
|
||||
}
|
||||
|
||||
private void DisplaySuggestions(IEnumerable suggestions, string filter)
|
||||
{
|
||||
if (_filter != filter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_actb.IsLoading = false;
|
||||
_actb.ItemsSelector.ItemsSource = suggestions;
|
||||
// Close drop down if there are no items
|
||||
if (_actb.IsDropDownOpen)
|
||||
{
|
||||
_actb.IsDropDownOpen = _actb.ItemsSelector.HasItems;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetSuggestionsAsync(object param)
|
||||
{
|
||||
if (param is object[] args)
|
||||
{
|
||||
string searchText = Convert.ToString(args[0]);
|
||||
if (args[1] is IComboSuggestionProvider provider)
|
||||
{
|
||||
IEnumerable list = provider.GetSuggestions(searchText);
|
||||
_actb.Dispatcher.BeginInvoke(new Action<IEnumerable, string>(DisplaySuggestions), DispatcherPriority.Background, list, searchText);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void GetFullCollectionAsync(object param)
|
||||
{
|
||||
if (param is IComboSuggestionProvider provider)
|
||||
{
|
||||
IEnumerable list = provider.GetFullCollection();
|
||||
_actb.Dispatcher.BeginInvoke(new Action<IEnumerable, string>(DisplaySuggestions), DispatcherPriority.Background, list, string.Empty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user