using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Tango.Core.Commands; using Tango.Core.EventArguments; using Tango.Core.ExtensionMethods; namespace Tango.Touch.Controls { public class TouchAutoComplete : TouchInput { private TextBox _textBox; private Popup _popup; private TouchListBox _listbox; public String Text { get { return (String)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(String), typeof(TouchAutoComplete), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); public String Watermark { get { return (String)GetValue(WatermarkProperty); } set { SetValue(WatermarkProperty, value); } } public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(String), typeof(TouchAutoComplete), new PropertyMetadata(null)); public IList ItemsSource { get { return (IList)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IList), typeof(TouchAutoComplete), new PropertyMetadata(null)); public IList EffectiveItemsSource { get { return (IList)GetValue(EffectiveItemsSourceProperty); } private set { SetValue(EffectiveItemsSourceProperty, value); } } public static readonly DependencyProperty EffectiveItemsSourceProperty = DependencyProperty.Register("EffectiveItemsSource", typeof(IList), typeof(TouchAutoComplete), new PropertyMetadata(null)); public IAutoCompleteProvider AutoCompleteProvider { get { return (IAutoCompleteProvider)GetValue(AutoCompleteProviderProperty); } set { SetValue(AutoCompleteProviderProperty, value); } } public static readonly DependencyProperty AutoCompleteProviderProperty = DependencyProperty.Register("AutoCompleteProvider", typeof(IAutoCompleteProvider), typeof(TouchAutoComplete), new PropertyMetadata(null)); public object SelectedItem { get { return (object)GetValue(SelectedItemProperty); } set { SetValue(SelectedItemProperty, value); } } public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(TouchAutoComplete), new PropertyMetadata(null, (d, e) => (d as TouchAutoComplete).OnSelectedItemChanged())); public String DisplayMemberPath { get { return (String)GetValue(DisplayMemberPathProperty); } set { SetValue(DisplayMemberPathProperty, value); } } public static readonly DependencyProperty DisplayMemberPathProperty = DependencyProperty.Register("DisplayMemberPath", typeof(String), typeof(TouchAutoComplete), new PropertyMetadata(null)); public DataTemplate ItemTemplate { get { return (DataTemplate)GetValue(ItemTemplateProperty); } set { SetValue(ItemTemplateProperty, value); } } public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(TouchAutoComplete), new PropertyMetadata(null)); public RelayCommand ItemSelectedCommand { get { return (RelayCommand)GetValue(ItemSelectedCommandProperty); } private set { SetValue(ItemSelectedCommandProperty, value); } } public static readonly DependencyProperty ItemSelectedCommandProperty = DependencyProperty.Register("ItemSelectedCommand", typeof(RelayCommand), typeof(TouchAutoComplete), new PropertyMetadata(null)); public double PopupHeight { get { return (double)GetValue(PopupHeightProperty); } set { SetValue(PopupHeightProperty, value); } } public static readonly DependencyProperty PopupHeightProperty = DependencyProperty.Register("PopupHeight", typeof(double), typeof(TouchAutoComplete), new PropertyMetadata(200.0)); public bool ForceItemSelection { get { return (bool)GetValue(ForceItemSelectionProperty); } set { SetValue(ForceItemSelectionProperty, value); } } public static readonly DependencyProperty ForceItemSelectionProperty = DependencyProperty.Register("ForceItemSelection", typeof(bool), typeof(TouchAutoComplete), new PropertyMetadata(true)); public TouchAutoComplete() { //AutoCompleteProvider = new AutoCompleteProvider((obj, filter) => { return obj.ToString().ToLower().StartsWith(filter.ToLower()); }); ItemSelectedCommand = new RelayCommand(() => OnSelectedItemChanged()); } public override void OnApplyTemplate() { base.OnApplyTemplate(); _textBox = GetTemplateChild("PART_TextBox") as TextBox; _popup = GetTemplateChild("PART_Popup") as Popup; _listbox = GetTemplateChild("PART_ListBox") as TouchListBox; _popup.RegisterForMouseOrTouchDown(OnPopupMouseDown); _textBox.PreviewKeyUp += _textBox_PreviewKeyUp; _textBox.GotFocus += _textBox_GotFocus; _textBox.LostFocus += _textBox_LostFocus; OnSelectedItemChanged(); } private void OnPopupMouseDown(object sender, MouseOrTouchEventArgs e) { e.Handled = true; } private void _textBox_LostFocus(object sender, RoutedEventArgs e) { _popup.IsOpen = false; if (ForceItemSelection) { if (EffectiveItemsSource != null && EffectiveItemsSource.Count > 0 && SelectedItem == null) { SelectedItem = EffectiveItemsSource[0]; var binding = BindingOperations.GetBindingExpressionBase(this, SelectedItemProperty); if (binding != null) { binding.UpdateSource(); } } } } private void _textBox_GotFocus(object sender, RoutedEventArgs e) { if (Text != null) { _textBox.CaretIndex = _textBox.Text.Length; } } private void _textBox_PreviewKeyUp(object sender, KeyEventArgs e) { if (AutoCompleteProvider != null && ItemsSource != null) { EffectiveItemsSource = AutoCompleteProvider.Filter(ItemsSource, Text); SelectedItem = null; if (EffectiveItemsSource.Count > 0) { _popup.IsOpen = true; _listbox.ScrollViewer.ScrollToTop(); } else { _popup.IsOpen = false; } } } private void OnSelectedItemChanged() { if (SelectedItem != null && _textBox != null) { Text = SelectedItem.GetPropertyValueByPath(DisplayMemberPath).ToString(); if (Text != null) { _textBox.CaretIndex = _textBox.Text.Length; } } else if (_textBox != null) { _textBox.Text = null; } if (_popup != null) { _popup.IsOpen = false; } } static TouchAutoComplete() { DefaultStyleKeyProperty.OverrideMetadata(typeof(TouchAutoComplete), new FrameworkPropertyMetadata(typeof(TouchAutoComplete))); } } }