From 338edba081dba2a2aefb634811be1cc84ec93d64 Mon Sep 17 00:00:00 2001 From: Avi Levkovich Date: Tue, 25 Aug 2020 10:08:01 +0300 Subject: merge --- .../Tango.SharedUI/Components/SelectedObject.cs | 6 +- .../Controls/AllSelectedCheckboxList.cs | 144 ++++++++++ .../Controls/PopupWithKeyboardFocus.cs | 42 --- .../Tango.SharedUI/Controls/SearchComboBox.cs | 317 ++++++--------------- .../Tango.SharedUI/Tango.SharedUI.csproj | 2 +- 5 files changed, 244 insertions(+), 267 deletions(-) create mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs delete mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs (limited to 'Software/Visual_Studio/Tango.SharedUI') diff --git a/Software/Visual_Studio/Tango.SharedUI/Components/SelectedObject.cs b/Software/Visual_Studio/Tango.SharedUI/Components/SelectedObject.cs index f91e93b5a..d85777292 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Components/SelectedObject.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Components/SelectedObject.cs @@ -7,18 +7,20 @@ using Tango.Core; namespace Tango.SharedUI.Components { - public class SelectedObject : ExtendedObject + public class SelectedObject : ExtendedObject { public event EventHandler IsSelectedChanged; private bool _isSelected; - public bool IsSelected { get { return _isSelected; } set { _isSelected = value; RaisePropertyChangedAuto(); IsSelectedChanged?.Invoke(this, new EventArgs()); } } + } + public class SelectedObject : SelectedObject + { private T _data; public T Data diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs new file mode 100644 index 000000000..6e3cb862f --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs @@ -0,0 +1,144 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using Tango.Core.Commands; +//using System.Collections; +using System.Linq; +using System.Collections; + +namespace Tango.SharedUI.Controls +{ + public class AllSelectedCheckboxList : ListBox + { + #region Properties + + private ItemsControl _itemsControl; + + public ItemsControl ItemsControl + { + get { return _itemsControl; } + set { _itemsControl = value; } + } + + public bool? AllSelected + { + get { return (bool?)GetValue(AllSelectedProperty); } + set + { + SetValue(AllSelectedProperty, value); + } + } + + public static readonly DependencyProperty AllSelectedProperty = + DependencyProperty.Register("AllSelected", typeof(bool?), typeof(AllSelectedCheckboxList), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnAllSelectedChanged))); + + + private static void OnAllSelectedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + AllSelectedCheckboxList l = o as AllSelectedCheckboxList; + var nv = e.NewValue; + l.AllSelectedChanged((bool?)nv); + } + + public static DependencyProperty ClickCheckBoxCommandProperty = DependencyProperty.Register("ClickCheckBoxCommand", typeof(RelayCommand), typeof(AllSelectedCheckboxList)); + public RelayCommand ClickCheckBoxCommand + { + get { return (RelayCommand)GetValue(ClickCheckBoxCommandProperty); } + private set { SetValue(ClickCheckBoxCommandProperty, value); } + } + + #endregion + + #region "Constructors" + + static AllSelectedCheckboxList() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(AllSelectedCheckboxList), new FrameworkPropertyMetadata(typeof(AllSelectedCheckboxList))); + + } + public AllSelectedCheckboxList() : base() + { + ClickCheckBoxCommand = new RelayCommand(ClickCheckBox); + } + + /// + /// Clicks the CheckBox.Update Selection ListBoxitem. + /// + /// The object. + private void ClickCheckBox(object obj) + { + if (obj is ListBoxItem) + { + ListBoxItem lbItem = obj as ListBoxItem; + CheckBox checkBox = lbItem.FindVisualChildren().FirstOrDefault(); + if (checkBox != null) + { + bool? check = checkBox.IsChecked; + if (check != null) + { + lbItem.IsSelected = (bool)check; + } + } + } + + if (SelectedItems.Count == 0) + { + AllSelected = false; + } + else if (Items.Count > 0 && SelectedItems.Count == Items.Count) + { + AllSelected = true; + } + else + { + AllSelected = null; + } + } + + #endregion + + #region Override + + /// + /// When overridden in a derived class, is invoked whenever application code or internal processes call . + /// + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + AllSelectedChanged(AllSelected); + + + + } + + protected override void OnSelectionChanged(SelectionChangedEventArgs e) + { + base.OnSelectionChanged(e); + foreach(var addItem in e.AddedItems.OfType()) + { + addItem.IsSelected = true; + } + foreach (var removeItem in e.RemovedItems.OfType()) + { + removeItem.IsSelected = false; + } + } + + #endregion + + private void AllSelectedChanged(bool? value) + { + if (value == null) + return; + SelectionMode = SelectionMode.Multiple; + if (value == true) + { + SelectAll(); + } + else + { + UnselectAll(); + } + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs deleted file mode 100644 index 9426b95cf..000000000 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs +++ /dev/null @@ -1,42 +0,0 @@ -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 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 = ""; - /// - /// Gets or sets the search text of TextBox. - /// - 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); } } - /// - /// The search items list property for popup items list - /// - public static readonly DependencyProperty SearchItemsListProperty = - DependencyProperty.Register("SearchItemsList", typeof(ListCollectionView), typeof(SearchComboBox), new PropertyMetadata(default(ObservableCollection))); - + 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); - } - - /// - /// Responds to a selection change by raising a event. - /// Change selection only on click on item - /// - /// Provides data for . - 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); - } - } + /// /// When overridden in a derived class, is invoked whenever application code or internal processes call . /// 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; } - /// - /// Called when [popup closed]. - /// Selection Index/Value will be set according to unfiltered whole list - /// - /// The sender. - /// The instance containing the event data. - 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().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 + } } diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj index edbb21a77..af809d25c 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj +++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj @@ -72,6 +72,7 @@ + @@ -86,7 +87,6 @@ MultiTransitionControl.xaml - -- cgit v1.3.1