aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.SharedUI/Controls
diff options
context:
space:
mode:
authorVictoria Plitt <Victoria.Plitt@twine-s.com>2020-08-05 00:28:12 +0300
committerVictoria Plitt <Victoria.Plitt@twine-s.com>2020-08-05 00:28:12 +0300
commit054b6ca55142fae5bb30a9b8f3301f7e71a92296 (patch)
tree13cd2dd8ba72af9b78a98ac56d1785a423be0e89 /Software/Visual_Studio/Tango.SharedUI/Controls
parent064bb0517aa7f8a1906761ae099cf44b785cff9f (diff)
downloadTango-054b6ca55142fae5bb30a9b8f3301f7e71a92296.tar.gz
Tango-054b6ca55142fae5bb30a9b8f3301f7e71a92296.zip
Added a new control SearchComboBox. Refactoring code filter of RmlsCollectionView.
Related Work Items: #3286
Diffstat (limited to 'Software/Visual_Studio/Tango.SharedUI/Controls')
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs42
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs308
2 files changed, 350 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs
new file mode 100644
index 000000000..9426b95cf
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs
@@ -0,0 +1,42 @@
+using MaterialDesignThemes.Wpf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls.Primitives;
+using System.Windows.Input;
+using System.Windows.Interop;
+
+namespace Tango.SharedUI.Controls
+{
+ public class PopupWithKeyboardFocus: ComboBoxPopup
+ {
+ [DllImport("user32.dll")]
+ static extern IntPtr SetActiveWindow(IntPtr hWnd);
+
+ static PopupWithKeyboardFocus()
+ {
+ EventManager.RegisterClassHandler(
+ typeof(PopupWithKeyboardFocus),
+ Popup.PreviewGotKeyboardFocusEvent,
+ new KeyboardFocusChangedEventHandler(OnPreviewGotKeyboardFocus),
+ true);
+ }
+
+ private static void OnPreviewGotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
+ {
+ var textBox = e.NewFocus as TextBoxBase;
+ if (textBox != null)
+ {
+ var hwndSource = PresentationSource.FromVisual(textBox) as HwndSource;
+ if (hwndSource != null)
+ {
+ SetActiveWindow(hwndSource.Handle);
+ }
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs
new file mode 100644
index 000000000..f9d65bd2b
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs
@@ -0,0 +1,308 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+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 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 string _searchText = "";
+ /// <summary>
+ /// Gets or sets the search text of TextBox.
+ /// </summary>
+ public string SearchText
+ {
+ get { return _searchText; }
+ set
+ {
+ if(_searchText != value && value != null)
+ {
+ _searchText = value;
+ }
+
+ }
+ }
+
+ public ListCollectionView SearchItemsList
+ {
+ get { return (ListCollectionView)GetValue(SearchItemsListProperty); }
+ set { SetValue(SearchItemsListProperty, 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 string SearchParam
+ {
+ get { return (string)GetValue(SearchParamProperty); }
+ set { SetValue(SearchParamProperty, value); }
+ }
+
+ public static readonly DependencyProperty SearchParamProperty =
+ DependencyProperty.Register("SearchParam", typeof(string), typeof(SearchComboBox), new FrameworkPropertyMetadata(""));
+
+ public System.Collections.IList SourceItems
+ {
+ get { return (System.Collections.IList)GetValue(SourceItemsProperty); }
+ set { SetValue(SourceItemsProperty, value); }
+ }
+
+ public static readonly DependencyProperty SourceItemsProperty =
+ DependencyProperty.Register("SourceItems", typeof(System.Collections.IList), typeof(SearchComboBox), new PropertyMetadata(default(System.Collections.IList)));
+
+
+ #endregion
+
+
+ #region Constructors
+
+ static SearchComboBox()
+ {
+ 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)
+ {
+ Popup.StaysOpen = false;
+ Popup.Opened += OnPopupOpened;
+ Popup.Closed += OnPopupClosed;
+
+ }
+ Editor = Template.FindName(PartEditor, this) as TextBox;
+ if(Editor != null)
+ {
+ Editor.TextChanged += OnEditorTextChanged;
+ Editor.MouseLeave += Editor_MouseLeave;
+ Editor.MouseEnter += Editor_MouseEnter;
+ }
+ }
+
+ #endregion
+
+ #region EventHandlers
+
+ private void Popup_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (Editor != null )
+ {
+ Editor.Focus();
+ Keyboard.Focus(Editor);
+ }
+ }
+
+ private void OnPopupOpened(object sender, EventArgs e)
+ {
+ SearchText = "";
+ InitSelectedList();
+ if (Editor != null )
+ {
+ Editor.Text = "";
+ Editor.Focus();
+ Editor.SelectionStart = 0;
+ Keyboard.Focus(Editor);
+ }
+ _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)
+ {
+ 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
+ {
+ var selvalue = SelectedValue;
+ SearchText = "";
+ SearchItemsList.Refresh();
+ SelectedValue = selvalue;
+ }
+ _savedSelectedIndex = -1;
+ }
+
+ private void OnEditorTextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (FetchTimer == null)
+ {
+ FetchTimer = new DispatcherTimer();
+ FetchTimer.Interval = TimeSpan.FromMilliseconds(100);
+ FetchTimer.Tick += OnFetchTimerTick;
+ }
+
+ 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)
+ {
+ FetchTimer.IsEnabled = false;
+ FetchTimer.Stop();
+ SearchText = Editor.Text;
+ OnTextChanged();
+ }
+
+ public virtual void OnTextChanged()
+ {
+ if (SearchItemsList != null)
+ {
+ SearchItemsList.Refresh();
+ }
+ if(SearchItemsList.Count > 0 && SelectedIndex != -1)
+ {
+ SelectedIndex = -1;// trick: all filtered items are displayed only with SelectedIndex = -1 , otherwise it is displayed 1 less
+ }
+ }
+
+ #endregion
+ }
+}