aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-08-25 17:50:22 +0300
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-08-25 17:50:22 +0300
commit9bc0807514a69d97fceab11d77bee02aff4eb3d9 (patch)
tree2c5ad002ab84443945943adc2ab531ce6fccda22 /Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs
parent26b6bf34090634edf23ed5ed1785560c024da02c (diff)
parent642dbff4c449d268d18ec4ca7f2ff267876dce14 (diff)
downloadTango-9bc0807514a69d97fceab11d77bee02aff4eb3d9.tar.gz
Tango-9bc0807514a69d97fceab11d77bee02aff4eb3d9.zip
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs')
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs317
1 files changed, 95 insertions, 222 deletions
diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs
index f9d65bd2b..8fc6483e9 100644
--- a/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs
+++ b/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs
@@ -1,104 +1,63 @@
using System;
+using System.Collections;
using System.Collections.ObjectModel;
+using System.ComponentModel;
using System.Diagnostics;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
+using System.Linq;
using System.Windows.Media;
using System.Windows.Threading;
namespace Tango.SharedUI.Controls
{
[TemplatePart(Name = SearchComboBox.PartEditor, Type = typeof(System.Windows.Controls.TextBox))]
- [TemplatePart(Name = SearchComboBox.PartPopup, Type = typeof(Popup))]
public class SearchComboBox : ComboBox
{
public const string PartEditor = "Search";
- public const string PartPopup = "PART_Popup";
- private int _savedSelectedIndex = -1;
- private bool _editorMouseLeaveFlag = false;
- #region Properties
-
- private TextBox _editor;
-
- public TextBox Editor
- {
- get { return _editor; }
- set { _editor = value; }
- }
-
-
- private Popup _popup;
-
- public Popup Popup
- {
- get { return _popup; }
- set { _popup = value; }
- }
-
- private DispatcherTimer _fetchTimer;
-
- public DispatcherTimer FetchTimer
- {
- get { return _fetchTimer; }
- set { _fetchTimer = value; }
- }
-
+ private TextBox _textBox;
+ private ListBox _listBox;
+ private ICollectionView _view;
- private string _searchText = "";
- /// <summary>
- /// Gets or sets the search text of TextBox.
- /// </summary>
- public string SearchText
+ #region Properties
+ public bool IsOpened
{
- get { return _searchText; }
- set
- {
- if(_searchText != value && value != null)
- {
- _searchText = value;
- }
-
- }
+ get { return (bool)GetValue(IsOpenedProperty); }
+ set { SetValue(IsOpenedProperty, value); }
}
+ public static readonly DependencyProperty IsOpenedProperty =
+ DependencyProperty.Register("IsOpened", typeof(bool), typeof(SearchComboBox), new PropertyMetadata(false, (d, e) => (d as SearchComboBox).OnIsOpenedChanged()));
- public ListCollectionView SearchItemsList
+ public String SearchProperty
{
- get { return (ListCollectionView)GetValue(SearchItemsListProperty); }
- set { SetValue(SearchItemsListProperty, value); }
+ get { return (String)GetValue(SearchPropertyProperty); }
+ set { SetValue(SearchPropertyProperty, value); }
}
- /// <summary>
- /// The search items list property for popup items list
- /// </summary>
- public static readonly DependencyProperty SearchItemsListProperty =
- DependencyProperty.Register("SearchItemsList", typeof(ListCollectionView), typeof(SearchComboBox), new PropertyMetadata(default(ObservableCollection<string>)));
-
+ public static readonly DependencyProperty SearchPropertyProperty =
+ DependencyProperty.Register("SearchProperty", typeof(String), typeof(SearchComboBox), new PropertyMetadata(null));
- public string SearchParam
+ public String SearchFilter
{
- get { return (string)GetValue(SearchParamProperty); }
- set { SetValue(SearchParamProperty, value); }
+ get { return (String)GetValue(SearchFilterProperty); }
+ set { SetValue(SearchFilterProperty, value); }
}
+ public static readonly DependencyProperty SearchFilterProperty =
+ DependencyProperty.Register("SearchFilter", typeof(String), typeof(SearchComboBox), new PropertyMetadata(null, (d, e) => (d as SearchComboBox).OnFilterChanged()));
- public static readonly DependencyProperty SearchParamProperty =
- DependencyProperty.Register("SearchParam", typeof(string), typeof(SearchComboBox), new FrameworkPropertyMetadata(""));
-
- public System.Collections.IList SourceItems
+ public IEnumerable ListItemsSource
{
- get { return (System.Collections.IList)GetValue(SourceItemsProperty); }
- set { SetValue(SourceItemsProperty, value); }
+ get { return (IEnumerable)GetValue(ListItemsSourceProperty); }
+ set { SetValue(ListItemsSourceProperty, value); }
}
-
- public static readonly DependencyProperty SourceItemsProperty =
- DependencyProperty.Register("SourceItems", typeof(System.Collections.IList), typeof(SearchComboBox), new PropertyMetadata(default(System.Collections.IList)));
-
+ public static readonly DependencyProperty ListItemsSourceProperty =
+ DependencyProperty.Register("ListItemsSource", typeof(IEnumerable), typeof(SearchComboBox), new PropertyMetadata(null));
#endregion
-
-
#region Constructors
static SearchComboBox()
@@ -106,203 +65,117 @@ namespace Tango.SharedUI.Controls
DefaultStyleKeyProperty.OverrideMetadata(typeof(SearchComboBox), new FrameworkPropertyMetadata(typeof(SearchComboBox)));
}
- public SearchComboBox()
- {
-
- }
-
#endregion //Constructors
-
- #region override
- protected override void OnLostMouseCapture(MouseEventArgs e)
- {
- if (Mouse.Captured == null)
- {
- if (e.OriginalSource == this)
- {
- //SetPopupState();
- }
- else if (IsDropDownOpen)
- {
- Mouse.Capture(this, CaptureMode.SubTree);
- }
- }
-
- base.OnLostMouseCapture(e);
- }
-
- /// <summary>
- /// Responds to a <see cref="T:System.Windows.Controls.ComboBox" /> selection change by raising a <see cref="E:System.Windows.Controls.Primitives.Selector.SelectionChanged" /> event.
- /// Change selection only on click on item
- /// </summary>
- /// <param name="e">Provides data for <see cref="T:System.Windows.Controls.SelectionChangedEventArgs" />.</param>
- protected override void OnSelectionChanged(SelectionChangedEventArgs e)
- {
- if (Editor == null || !Editor.IsKeyboardFocused || ( Editor.IsKeyboardFocused && _editorMouseLeaveFlag ) )
- {
- base.OnSelectionChanged(e);
- if (e.AddedItems.Count != 0 && SelectedIndex != this.SourceItems.IndexOf(e.AddedItems[0]))
- {
- SelectedValue = e.AddedItems[0];
- }
- }
- e.Handled = true;
- }
-
-
- #endregion
-
#region Initialization
-
- void InitSelectedList()
- {
- if (SearchItemsList == null)
- {
- SearchItemsList = new ListCollectionView(this.SourceItems);
- if (String.IsNullOrEmpty(SearchParam))
- SearchItemsList.Filter = null;
- else
- {
- SearchItemsList.Filter = (ob) =>
- {
- var prop = ob.GetType().GetProperty(SearchParam);
- if (prop == null)
- {
- return true;
- }
- string value = prop.GetValue(ob, null) as string;
- return value != null && (String.IsNullOrEmpty(SearchText) || value.ToLower().Contains(SearchText.ToLower()));
- };
- }
- Binding mbinding = new Binding("SearchItems");
- mbinding.Mode = BindingMode.Default;
- mbinding.Source = this;
- mbinding.Path = new PropertyPath("SearchItemsList");
-
- SetBinding(ComboBox.ItemsSourceProperty, mbinding);
- }
- }
+
/// <summary>
/// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />.
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
-
- var binding1 = BindingOperations.GetBinding(this, ComboBox.ItemsSourceProperty);
- SetBinding(SearchComboBox.SourceItemsProperty, binding1);
- Popup = Template.FindName(PartPopup, this) as Popup;
-
- if (Popup != null)
+
+ _textBox = GetTemplateChild(PartEditor) as TextBox;
+ if(_textBox != null)
{
- Popup.StaysOpen = false;
- Popup.Opened += OnPopupOpened;
- Popup.Closed += OnPopupClosed;
-
+ _textBox.PreviewKeyDown += _textBox_KeyDown;
}
- Editor = Template.FindName(PartEditor, this) as TextBox;
- if(Editor != null)
+ _listBox = GetTemplateChild("list") as ListBox;
+ if(_listBox != null)
{
- Editor.TextChanged += OnEditorTextChanged;
- Editor.MouseLeave += Editor_MouseLeave;
- Editor.MouseEnter += Editor_MouseEnter;
+ _listBox.PreviewKeyDown += _listBox_PreviewKeyDown;
+ _listBox.PreviewMouseLeftButtonUp += _listBox_PreviewMouseLeftButtonUp;
}
}
#endregion
- #region EventHandlers
-
- private void Popup_KeyDown(object sender, KeyEventArgs e)
+ #region Event Handlers
+ private void _listBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
- if (Editor != null )
+ if (e.Key == Key.Return)
{
- Editor.Focus();
- Keyboard.Focus(Editor);
+ IsOpened = false;
+ SelectedItem = _listBox.SelectedItem;
}
}
- private void OnPopupOpened(object sender, EventArgs e)
+ private void _textBox_KeyDown(object sender, KeyEventArgs e)
{
- SearchText = "";
- InitSelectedList();
- if (Editor != null )
+ if (e.Key == Key.Down)
{
- Editor.Text = "";
- Editor.Focus();
- Editor.SelectionStart = 0;
- Keyboard.Focus(Editor);
+ _listBox.SelectedIndex = 0;
+ _listBox.Focus();
+ Keyboard.Focus(_listBox);
}
- _savedSelectedIndex = SelectedIndex;
}
- /// <summary>
- /// Called when [popup closed].
- /// Selection Index/Value will be set according to unfiltered whole list
- /// </summary>
- /// <param name="sender">The sender.</param>
- /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
- private void OnPopupClosed(object sender, EventArgs e)
+ private void _listBox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
- if(SelectedIndex == -1 && _savedSelectedIndex >=0)// selection item was set to null for filtering but not selected, return to prev value
- {
- SearchText = "";
- SearchItemsList.Refresh();
- SelectedValue = SearchItemsList.GetItemAt(_savedSelectedIndex);
- }
- if(this.SourceItems.Count != SearchItemsList.Count)//selection was changed on filtered list - replace to real selection index
+ if (!(e.OriginalSource is Thumb))
{
- var selvalue = SelectedValue;
- SearchText = "";
- SearchItemsList.Refresh();
- SelectedValue = selvalue;
+ IsOpened = false;
+ SelectedItem = _listBox.SelectedItem;
}
- _savedSelectedIndex = -1;
}
- private void OnEditorTextChanged(object sender, TextChangedEventArgs e)
+ private async void OnIsOpenedChanged()
{
- if (FetchTimer == null)
+ if (IsOpened)
{
- FetchTimer = new DispatcherTimer();
- FetchTimer.Interval = TimeSpan.FromMilliseconds(100);
- FetchTimer.Tick += OnFetchTimerTick;
+ _listBox.SelectedItem = SelectedItem;
+ SearchFilter = "";
+ await Task.Delay(100);
+ _textBox.Focus();
+
+ Keyboard.Focus(_textBox);
}
-
- FetchTimer.IsEnabled = true;
- FetchTimer.Start();
- }
-
- private void Editor_MouseEnter(object sender, MouseEventArgs e)
- {
- _editorMouseLeaveFlag = false;
}
- private void Editor_MouseLeave(object sender, MouseEventArgs e)
- {
- _editorMouseLeaveFlag = true;
- }
-
- private void OnFetchTimerTick(object sender, EventArgs e)
+ private void OnFilterChanged()
{
- FetchTimer.IsEnabled = false;
- FetchTimer.Stop();
- SearchText = Editor.Text;
- OnTextChanged();
+ _view?.Refresh();
}
- public virtual void OnTextChanged()
+ #endregion
+ #region Override
+
+ protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
- if (SearchItemsList != null)
- {
- SearchItemsList.Refresh();
- }
- if(SearchItemsList.Count > 0 && SelectedIndex != -1)
+ base.OnItemsSourceChanged(oldValue, newValue);
+
+ if (ItemsSource != null)
{
- SelectedIndex = -1;// trick: all filtered items are displayed only with SelectedIndex = -1 , otherwise it is displayed 1 less
+ ListItemsSource = ItemsSource.Cast<Object>().ToList();
+
+ _view = CollectionViewSource.GetDefaultView(ListItemsSource);
+ _view.Filter = (x) =>
+ {
+ if (String.IsNullOrWhiteSpace(SearchFilter) || SearchFilter == null) return true;
+
+ if (x != null)
+ {
+ var prop = x.GetType().GetProperty(SearchProperty);
+
+ // var prop = x.GetType().GetProperty(SearchProperty, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
+ if (prop != null)
+ {
+ String propValue = prop.GetValue(x).ToString();
+ return propValue.ToLower().Contains(SearchFilter.ToLower());
+ }
+ }
+
+ return false;
+ };
}
}
+ protected override void OnSelectionChanged(SelectionChangedEventArgs e)
+ {
+ base.OnSelectionChanged(e);
+ }
+
#endregion
+
}
}