From 00a491d93733d4625ad329b2ba8237f445364b3f Mon Sep 17 00:00:00 2001 From: Mirta Date: Wed, 30 Dec 2020 16:39:52 +0200 Subject: merge --- .../Controls/AllSelectedCheckboxList.cs | 144 ------ .../Tango.SharedUI/Controls/MultiSelectComboBox.cs | 344 --------------- .../Controls/MultiSelectComboBoxItem.cs | 39 -- .../Tango.SharedUI/Controls/MultiSelectDataGrid.cs | 2 +- .../Tango.SharedUI/Controls/NavigationControl.cs | 366 +++++----------- .../Controls/ScriptEditorControl.xaml | 113 +++++ .../Controls/ScriptEditorControl.xaml.cs | 488 +++++++++++++++++++++ .../Tango.SharedUI/Controls/SearchComboBox.cs | 269 ------------ 8 files changed, 713 insertions(+), 1052 deletions(-) delete mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs delete mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectComboBox.cs delete mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectComboBoxItem.cs create mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml create mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs delete mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs (limited to 'Software/Visual_Studio/Tango.SharedUI/Controls') diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs deleted file mode 100644 index 6e3cb862f..000000000 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs +++ /dev/null @@ -1,144 +0,0 @@ -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/MultiSelectComboBox.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectComboBox.cs deleted file mode 100644 index 153b36804..000000000 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectComboBox.cs +++ /dev/null @@ -1,344 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -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 System.ComponentModel; -using System.Windows.Controls.Primitives; -using System.Windows.Threading; -using System.Diagnostics; - -namespace Tango.SharedUI.Controls -{ - internal sealed class MultiSelectComboBoxTemplateSelector : DataTemplateSelector - { - public override DataTemplate SelectTemplate(object item, DependencyObject container) - { - FrameworkElement element = container as FrameworkElement; - if (element != null && item != null && item is MultiSelectComboBoxItem) - return element.FindResource("CheckItem") as DataTemplate; - - return element.FindResource("SearchItem") as DataTemplate; ; - - } - } - - [TemplatePart(Name = MultiSelectComboBox.PartEditor, Type = typeof(TextBox))] - [TemplatePart(Name = MultiSelectComboBox.PartPopup, Type = typeof(Popup))] - public class MultiSelectComboBox : Control - { - #region Fields - public const string PartEditor = "Edit_PART"; - public const string PartPopup = "MultiSel_Popup"; - private ItemsControl _items_control; - private bool _isLoaded; - #endregion - #region "Constructors" - - static MultiSelectComboBox() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(typeof(MultiSelectComboBox))); - - } - public MultiSelectComboBox() : base() - { - SelectedItemsList = new ObservableCollection(); - RemoveAllCommand = new RelayCommand(RemoveAllSelectedItems, CanRemoveAllSelectedItems); - RemoveItemCommand = new RelayCommand(RemoveSelectedItem); - AddItemCommand = new RelayCommand(AddSelectedItem); - SearchText = new MultiSelectComboBoxSearchItem(); - Loaded += MultiSelectComboBox_Loaded; - _isLoaded = false; - - - } - #endregion - - #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; } - } - - public ObservableCollection SelectedItemsList - { - get { return (ObservableCollection)GetValue(SelectedItemsListProperty); } - set { SetValue(SelectedItemsListProperty, value); } - } - - public static readonly DependencyProperty SelectedItemsListProperty = - DependencyProperty.Register("SelectedItemsList", typeof(ObservableCollection), typeof(MultiSelectComboBox), new PropertyMetadata(default(ObservableCollection))); - - - public ListCollectionView SearchItemsList - { - get { return (ListCollectionView)GetValue(SearchItemsListProperty); } - set { SetValue(SearchItemsListProperty, value); } - } - /// - /// The search items list property for popup items list - /// - public static readonly DependencyProperty SearchItemsListProperty = - DependencyProperty.Register("SearchItemsList", typeof(ListCollectionView), typeof(MultiSelectComboBox), new PropertyMetadata(default(ObservableCollection))); - - public ObservableCollection Items - { - get { return (ObservableCollection)GetValue(ItemsProperty); } - set { SetValue(ItemsProperty, value); } - } - - public static readonly DependencyProperty ItemsProperty = - DependencyProperty.Register("Items", typeof(ObservableCollection), typeof(MultiSelectComboBox), new PropertyMetadata(default(ObservableCollection))); - - - public bool IsToggleChecked - { - get { return (bool)GetValue(IsToggleCheckedProperty); } - set { SetValue(IsToggleCheckedProperty, value); } - } - - public static readonly DependencyProperty IsToggleCheckedProperty = - DependencyProperty.Register("IsToggleChecked", typeof(bool), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(false)); - - private MultiSelectComboBoxSearchItem _searchText; - /// - /// Gets or sets the search text of TextBox. - /// - public MultiSelectComboBoxSearchItem SearchText - { - get { return _searchText; } - set - { - _searchText = value; - OnTextChanged(); - } - } - #endregion - - private void MultiSelectComboBox_Loaded(object sender, RoutedEventArgs e) - { - if (!_isLoaded) - { - ToggleButton b2 = GetTemplateChild("MultiSelToggleButton") as ToggleButton; - if (b2 != null) - { - // ct.LoadContent(); - _items_control = b2.Template.FindName("SelectedItemsControl", b2) as ItemsControl; - if (_items_control != null) - { - var wrapPanel = _items_control.FindChild(); - if (wrapPanel != null) - { - _items_control.Bind(ItemsControl.HeightProperty, wrapPanel, WrapPanel.ActualHeightProperty, BindingMode.OneWay); - _isLoaded = true; - - var searchItem =(_items_control.ItemContainerGenerator.ContainerFromItem(SearchText)); - Editor = searchItem.FindVisualChildren< TextBox>().FirstOrDefault(x => x.Name == PartEditor); - if (Editor != null) - { - Editor.TextChanged += OnEditorTextChanged; - Editor.PreviewKeyDown += OnEditorKeyDown; - Editor.LostFocus += OnEditorLostFocus; - Editor.GotFocus += OnEditorGotFocus; - } - } - } - this.GotFocus += SelTextBox_GotFocus; - } - } - } - - void OnTextChanged() - { - if(SearchItemsList != null) - { - if (String.IsNullOrEmpty(SearchText.Text)) - SearchItemsList.Filter = null; - else - SearchItemsList.Filter = new Predicate(o => (((string)o).ToLower().Contains(SearchText.Text.ToLower()))); - } - } - /// - /// When overridden in a derived class, is invoked whenever application code or internal processes call . - /// - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - if (SelectedItemsList == null) - SelectedItemsList = new ObservableCollection(); - SelectedItemsList.Add(SearchText); - - SearchItemsList = new ListCollectionView(this.Items); - Popup = Template.FindName(PartPopup, this) as Popup; - - - if (Popup != null) - { - Popup.StaysOpen = false; - Popup.Opened += OnPopupOpened; - Popup.Closed += OnPopupClosed; - } - } - - private void OnEditorTextChanged(object sender, TextChangedEventArgs e) - { - if (FetchTimer == null) - { - FetchTimer = new DispatcherTimer(); - FetchTimer.Interval = TimeSpan.FromMilliseconds(500); - FetchTimer.Tick += OnFetchTimerTick; - } - FetchTimer.IsEnabled = false; - FetchTimer.Stop(); - IsToggleChecked = true; - - FetchTimer.IsEnabled = true; - FetchTimer.Start(); - - } - - private void OnFetchTimerTick(object sender, EventArgs e) - { - FetchTimer.IsEnabled = false; - FetchTimer.Stop(); - SearchText.Text = Editor.Text; - OnTextChanged(); - } - - private void OnEditorKeyDown(object sender, KeyEventArgs e) - { - IsToggleChecked = true; - } - - private void OnEditorLostFocus(object sender, RoutedEventArgs e) - { - if (!IsKeyboardFocusWithin) - { - IsToggleChecked = false; - } - } - - private void SelTextBox_GotFocus(object sender, RoutedEventArgs e) - { - Editor?.Focus(); - } - - private void OnEditorGotFocus(object sender, RoutedEventArgs e) - { - IsToggleChecked = true; - } - - private void OnPopupOpened(object sender, EventArgs e) - { - - } - private void OnPopupClosed(object sender, EventArgs e) - { - IsToggleChecked = false; - - } - #region Commands - /// - /// The remove all command property for clear SelectedItemsList - /// - public static DependencyProperty RemoveAllCommandProperty = DependencyProperty.Register("RemoveAllCommand", typeof(RelayCommand), typeof(MultiSelectComboBox)); - public RelayCommand RemoveAllCommand - { - get { return (RelayCommand)GetValue(RemoveAllCommandProperty); } - private set { SetValue(RemoveAllCommandProperty, value); } - } - - /// - /// The remove item from SelectedItemsList command property - /// - public static DependencyProperty RemoveItemCommandProperty = DependencyProperty.Register("RemoveItemCommand", typeof(RelayCommand), typeof(MultiSelectComboBox)); - public RelayCommand RemoveItemCommand - { - get { return (RelayCommand)GetValue(RemoveItemCommandProperty); } - private set { SetValue(RemoveItemCommandProperty, value); } - } - - /// - /// The add item to SelectedItemsList command property - /// - public static DependencyProperty AddItemCommandProperty = DependencyProperty.Register("AddItemCommand", typeof(RelayCommand), typeof(MultiSelectComboBox)); - public RelayCommand AddItemCommand - { - get { return (RelayCommand)GetValue(AddItemCommandProperty); } - private set { SetValue(AddItemCommandProperty, value); } - } - - /// - /// Removes the selected item. - /// - /// The item. - private void RemoveSelectedItem(IMultiSelectComboBoxItem item) - { - SelectedItemsList.Remove(item); - RemoveAllCommand.RaiseCanExecuteChanged(); - } - - /// - /// Adds the selected item. - /// - /// The item. - private void AddSelectedItem(string item) - { - if (SelectedItemsList.Any(x => (x as IMultiSelectComboBoxItem).Text == item)) - return; - SelectedItemsList.Insert(SelectedItemsList.Count - 1, new MultiSelectComboBoxItem(item)); - RemoveAllCommand.RaiseCanExecuteChanged(); - } - /// - /// Removes all selected items. - /// - private void RemoveAllSelectedItems() - { - int index = SelectedItemsList.Count - 2; - while (index >= 0) - { - SelectedItemsList.RemoveAt(index--); - } - RemoveAllCommand.RaiseCanExecuteChanged(); - } - private bool CanRemoveAllSelectedItems() - { - return (SelectedItemsList != null && SelectedItemsList.Count > 1); - } - #endregion - - - } -} diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectComboBoxItem.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectComboBoxItem.cs deleted file mode 100644 index 2dcaa977a..000000000 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectComboBoxItem.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.SharedUI.Controls -{ - interface IMultiSelectComboBoxItem - { - string Text { get; set; } - } - - public class MultiSelectComboBoxItem : IMultiSelectComboBoxItem - { - public string Text { get; set; } - public MultiSelectComboBoxItem(string text) - { - Text = text; - } - public override string ToString() - { - return Text; - } - } - - public class MultiSelectComboBoxSearchItem : IMultiSelectComboBoxItem - { - public string Text { get; set; } - public MultiSelectComboBoxSearchItem(string text = "") - { - Text = text; - } - public override string ToString() - { - return Text; - } - } -} diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectDataGrid.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectDataGrid.cs index 12c4645e3..8f54a2ce4 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectDataGrid.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/MultiSelectDataGrid.cs @@ -9,7 +9,7 @@ using System.Windows.Controls; namespace Tango.SharedUI.Controls { - public class MultiSelectDataGrid : DoubleClickDataGrid + public class MultiSelectDataGrid : DataGrid { public IList SelectedItemsList { diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs index cefdbbfd6..b3869daff 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Diagnostics; using System.Linq; using System.Text; -using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -13,7 +11,6 @@ using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Threading; -using Tango.Core; using Tango.SharedUI.Helpers; namespace Tango.SharedUI.Controls @@ -21,17 +18,7 @@ namespace Tango.SharedUI.Controls [ContentProperty(nameof(Elements))] public class NavigationControl : UserControl { - private event Action NavigationCompleted; - public event EventHandler SelectedElementChanged; - private Thread _navigationThread; - private bool _preventSelectedObjectNavigation; - private ProducerConsumerQueue _navigationQueue; - - private class NavigationQueueItem - { - public NavigationElement FromElement { get; set; } - public NavigationElement ToElement { get; set; } - } + private Action _onCompleted; #region Transition Types @@ -186,24 +173,6 @@ namespace Tango.SharedUI.Controls #region Properties - - - public object SelectedObject - { - get { return (object)GetValue(SelectedObjectProperty); } - set { SetValue(SelectedObjectProperty, value); } - } - public static readonly DependencyProperty SelectedObjectProperty = - DependencyProperty.Register("SelectedObject", typeof(object), typeof(NavigationControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (d, e) => (d as NavigationControl).OnSelectedObjectChanged())); - - private void OnSelectedObjectChanged() - { - if (SelectedObject != null && !_preventSelectedObjectNavigation) - { - NavigateTo(SelectedObject); - } - } - public ObservableCollection Elements { get { return (ObservableCollection)GetValue(ElementsProperty); } @@ -218,7 +187,7 @@ namespace Tango.SharedUI.Controls set { SetValue(SelectedElementProperty, value); } } public static readonly DependencyProperty SelectedElementProperty = - DependencyProperty.Register("SelectedElement", typeof(FrameworkElement), typeof(NavigationControl), new FrameworkPropertyMetadata(null, (d, e) => (d as NavigationControl).OnSelectedElementChanged(e.OldValue as FrameworkElement, e.NewValue as FrameworkElement))); + DependencyProperty.Register("SelectedElement", typeof(FrameworkElement), typeof(NavigationControl), new PropertyMetadata(null, (d, e) => (d as NavigationControl).OnSelectedElementChanged(e.OldValue as FrameworkElement, e.NewValue as FrameworkElement))); public TransitionTypes TransitionType { @@ -252,13 +221,7 @@ namespace Tango.SharedUI.Controls public static readonly DependencyProperty KeepElementsAttachedProperty = DependencyProperty.Register("KeepElementsAttached", typeof(bool), typeof(NavigationControl), new PropertyMetadata(false)); - public bool GalleryMode - { - get { return (bool)GetValue(GalleryModeProperty); } - set { SetValue(GalleryModeProperty, value); } - } - public static readonly DependencyProperty GalleryModeProperty = - DependencyProperty.Register("GalleryMode", typeof(bool), typeof(NavigationControl), new PropertyMetadata(false)); + public int SelectedIndex { @@ -316,9 +279,7 @@ namespace Tango.SharedUI.Controls /// public static String GetNavigationName(FrameworkElement element) { - var name = element.GetValue(NavigationName).ToStringSafe(); - if (String.IsNullOrEmpty(name)) name = element.GetType().Name; - return name; + return element.GetValue(NavigationName).ToStringSafe(); } #endregion @@ -334,11 +295,6 @@ namespace Tango.SharedUI.Controls Content = _grid; Elements = new ObservableCollection(); Loaded += NavigationControl_Loaded; - - _navigationQueue = new ProducerConsumerQueue(); - _navigationThread = new Thread(NavigationThread); - _navigationThread.IsBackground = true; - _navigationThread.Start(); } #endregion @@ -391,8 +347,6 @@ namespace Tango.SharedUI.Controls } else { - Elements.ToList().ForEach(x => x.FocusVisualStyle = null); - var toRemove = _grid.Children.OfType().ToList().Where(x => !Elements.Contains(x.Element)).ToList(); var toAdd = Elements.Where(x => !_grid.Children.OfType().Select(y => y.Element).ToList().Contains(x)).ToList(); @@ -454,181 +408,135 @@ namespace Tango.SharedUI.Controls private void Navigate(NavigationElement fromElement, NavigationElement toElement) { - _navigationQueue.BlockEnqueue(new NavigationQueueItem() + if (toElement == null || toElement == fromElement) { - FromElement = fromElement, - ToElement = toElement, - }); - } + _onCompleted?.Invoke(); + } - private void NavigationThread() - { - try + if (fromElement != null) { - while (true) - { - var item = _navigationQueue.BlockDequeue(); - - var navigationCompleted = false; - - NavigationElement fromElement = item.FromElement; - NavigationElement toElement = item.ToElement; - - Dispatcher.BeginInvoke(new Action(() => - { - if (toElement == null || toElement == fromElement) - { - //navigationCompleted = true; - Debug.WriteLine("NavigationControl: THIS MIGHT CAUSE PROBLEMS !!"); - } + DoubleAnimation toAnimation = new DoubleAnimation(); + toAnimation.Duration = TransitionDuration; - if (fromElement != null) - { - DoubleAnimation toAnimation = new DoubleAnimation(); - toAnimation.Duration = TransitionDuration; - - DoubleAnimation fromAnimation = new DoubleAnimation(); - fromAnimation.Duration = TransitionDuration; + DoubleAnimation fromAnimation = new DoubleAnimation(); + fromAnimation.Duration = TransitionDuration; - int fromIndex = Elements.IndexOf(fromElement.Element); - int toIndex = Elements.IndexOf(toElement.Element); + int fromIndex = Elements.IndexOf(fromElement.Element); + int toIndex = Elements.IndexOf(toElement.Element); - fromElement.Reset(); - toElement.Reset(); + fromElement.Reset(); + toElement.Reset(); - fromAnimation.Completed += (_, __) => - { - fromElement.Deactivate(!KeepElementsAttached); - }; - - bool completed = false; - - toAnimation.Completed += (_, __) => - { - if (!completed) - { - completed = true; + fromAnimation.Completed += (_, __) => + { + fromElement.Deactivate(!KeepElementsAttached); + }; - INavigationView fromNavigationView = fromElement.Element as INavigationView; - INavigationView toNavigationView = toElement.Element as INavigationView; + bool completed = false; - if (fromNavigationView != null) - { - fromNavigationView.OnNavigatedFrom(); - } - if (toNavigationView != null) - { - toNavigationView.OnNavigatedTo(); - } + toAnimation.Completed += (_, __) => + { + if (!completed) + { + completed = true; - INavigationViewModel fromVM = fromElement.Element.DataContext as INavigationViewModel; - INavigationViewModel toVM = toElement.Element.DataContext as INavigationViewModel; + INavigationView fromNavigationView = fromElement.Element as INavigationView; + INavigationView toNavigationView = toElement.Element as INavigationView; - if (fromVM != null && fromVM != toVM) fromVM.OnNavigatedFrom(); - if (toVM != null) toVM.OnNavigatedTo(); + if (fromNavigationView != null) + { + fromNavigationView.OnNavigatedFrom(); + } + if (toNavigationView != null) + { + toNavigationView.OnNavigatedTo(); + } - navigationCompleted = true; - } - }; + INavigationViewModel fromVM = fromElement.Element.DataContext as INavigationViewModel; + INavigationViewModel toVM = toElement.Element.DataContext as INavigationViewModel; - switch (TransitionType) - { - case TransitionTypes.Fade: - fromAnimation.From = 1; - fromAnimation.To = 0; + if (fromVM != null && fromVM != toVM) fromVM.OnNavigatedFrom(); + if (toVM != null) toVM.OnNavigatedTo(); - toAnimation.From = 0; - toAnimation.To = 1; + _onCompleted?.Invoke(); + } + }; - fromElement.AnimateOpacity(fromAnimation); - toElement.AnimateOpacity(toAnimation); + switch (TransitionType) + { + case TransitionTypes.Fade: + fromAnimation.From = 1; + fromAnimation.To = 0; - break; - case TransitionTypes.Zoom: - fromAnimation.From = 1; - fromAnimation.To = 0; + toAnimation.From = 0; + toAnimation.To = 1; - toAnimation.From = 0; - toAnimation.To = 1; + fromElement.AnimateOpacity(fromAnimation); + toElement.AnimateOpacity(toAnimation); - fromElement.AnimateScale(fromAnimation); - toElement.AnimateScale(toAnimation); + break; + case TransitionTypes.Zoom: + fromAnimation.From = 1; + fromAnimation.To = 0; - break; - case TransitionTypes.Slide: + toAnimation.From = 0; + toAnimation.To = 1; - if (toIndex > fromIndex || GalleryMode) - { - fromAnimation.From = 0; - fromAnimation.To = -ActualWidth; + fromElement.AnimateScale(fromAnimation); + toElement.AnimateScale(toAnimation); - toAnimation.From = ActualWidth; - toAnimation.To = 0; - } - else - { - fromAnimation.From = 0; - fromAnimation.To = ActualWidth; + break; + case TransitionTypes.Slide: - toAnimation.From = -ActualWidth; - toAnimation.To = 0; - } - - fromElement.AnimateTranslateX(fromAnimation); - toElement.AnimateTranslateX(toAnimation); - - break; - } + if (toIndex > fromIndex) + { + fromAnimation.From = 0; + fromAnimation.To = -ActualWidth; - if (TransitionAlwaysFades && TransitionType != TransitionTypes.Fade) - { - DoubleAnimation fromFadeAnimation = new DoubleAnimation(); - fromFadeAnimation.From = 1; - fromFadeAnimation.To = 0; - fromFadeAnimation.Duration = TransitionDuration; - - DoubleAnimation toFadeAnimation = new DoubleAnimation(); - toFadeAnimation.From = 0; - toFadeAnimation.To = 1; - toFadeAnimation.Duration = TransitionDuration; - - fromElement.AnimateOpacity(fromFadeAnimation); - toElement.AnimateOpacity(toFadeAnimation); - } - - fromElement.Activate(); - toElement.Activate(); + toAnimation.From = ActualWidth; + toAnimation.To = 0; } else { - toElement.Activate(); - toElement.Reset(); + fromAnimation.From = 0; + fromAnimation.To = ActualWidth; - INavigationViewModel toVM = toElement.Element.DataContext as INavigationViewModel; - if (toVM != null) toVM.OnNavigatedTo(); - - navigationCompleted = true; + toAnimation.From = -ActualWidth; + toAnimation.To = 0; } - })); - for (int i = 0; i < 30; i++) - { - if (navigationCompleted) - { - break; - } - Thread.Sleep(100); - } + fromElement.AnimateTranslateX(fromAnimation); + toElement.AnimateTranslateX(toAnimation); - Dispatcher.BeginInvoke(new Action(() => - { - NavigationCompleted?.Invoke(); - })); + break; + } + + if (TransitionAlwaysFades && TransitionType != TransitionTypes.Fade) + { + DoubleAnimation fromFadeAnimation = new DoubleAnimation(); + fromFadeAnimation.From = 1; + fromFadeAnimation.To = 0; + fromFadeAnimation.Duration = TransitionDuration; + + DoubleAnimation toFadeAnimation = new DoubleAnimation(); + toFadeAnimation.From = 0; + toFadeAnimation.To = 1; + toFadeAnimation.Duration = TransitionDuration; + + fromElement.AnimateOpacity(fromFadeAnimation); + toElement.AnimateOpacity(toFadeAnimation); } + + fromElement.Activate(); + toElement.Activate(); } - catch + else { - + toElement.Activate(); + toElement.Reset(); + + INavigationViewModel toVM = toElement.Element.DataContext as INavigationViewModel; + if (toVM != null) toVM.OnNavigatedTo(); } } @@ -639,14 +547,6 @@ namespace Tango.SharedUI.Controls protected virtual void OnSelectedElementChanged(FrameworkElement fromElement, FrameworkElement toElement) { Navigate(GetElementContainer(fromElement), GetElementContainer(toElement)); - SelectedElementChanged?.Invoke(this, toElement); - - if (toElement != null) - { - _preventSelectedObjectNavigation = true; - SelectedObject = GetNavigationName(toElement); - _preventSelectedObjectNavigation = false; - } } #endregion @@ -668,67 +568,27 @@ namespace Tango.SharedUI.Controls return NavigateTo(navigationName, null); } - public FrameworkElement NavigateTo(Object obj) - { - return NavigateTo(obj.ToString(), null); - } - public FrameworkElement NavigateTo(String navigationName, Action onCompleted = null) { - Action completed = null; - - completed = () => - { - try - { - onCompleted?.Invoke(); - } - catch { } - NavigationCompleted -= completed; - }; - - NavigationCompleted += completed; + _onCompleted = onCompleted; var element = Elements.SingleOrDefault(x => GetNavigationName(x) == navigationName || x.GetType().Name == navigationName); - Task.Factory.StartNew(() => + if (element != null) { - Thread.Sleep(10); - - Dispatcher.BeginInvoke(new Action(async () => + if (SelectedElement == element) { - if (element != null) - { - if (SelectedElement == element) - { - await Task.Delay((int)TransitionDuration.TimeSpan.TotalMilliseconds * 2); - NavigationCompleted?.Invoke(); - } - else - { - SelectedElement = element; - } - } - })); - }); + _onCompleted?.Invoke(); + } + else + { + SelectedElement = element; + } + } return element; } - public Task NavigateToAsync(String navigationName) - { - TaskCompletionSource source = new TaskCompletionSource(); - - FrameworkElement view = null; - - view = NavigateTo(navigationName, () => - { - source.SetResult(view); - }); - - return source.Task; - } - public FrameworkElement GetElement(String navigationName) { return Elements.SingleOrDefault(x => GetNavigationName(x) == navigationName || x.GetType().Name == navigationName); @@ -741,11 +601,6 @@ namespace Tango.SharedUI.Controls return element; } - public String GetSelectedElementNavigationName() - { - return GetNavigationName(SelectedElement); - } - /// /// This method needs to be called in order for // the element to print visibly at the correct size. @@ -768,6 +623,7 @@ namespace Tango.SharedUI.Controls catch { } } } + #endregion } } diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml b/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml new file mode 100644 index 000000000..817297191 --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs new file mode 100644 index 000000000..3fe87c7e2 --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs @@ -0,0 +1,488 @@ +using ICSharpCode.AvalonEdit.CodeCompletion; +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Editing; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +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 System.Windows.Threading; +using System.Xml; +using Tango.Core.Commands; +using Tango.Scripting; +using Tango.SharedUI; +using Tango.SharedUI.Helpers; + +namespace Tango.SharedUI.Controls +{ + /// + /// Represents a C# script editor control. + /// + /// + /// + public partial class ScriptEditorControl : UserControl + { + #region Completion + + /// + /// Represents an auto complete item. + /// + /// + internal class CompletionData : ICompletionData + { + private String _description; + + /// + /// Gets or sets the icon source. + /// + public BitmapSource Source { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The text. + /// The description. + public CompletionData(string text, String description) + { + this.Text = text; + _description = description; + } + + /// + /// Gets the image. + /// + public System.Windows.Media.ImageSource Image + { + get { return Source; } + } + + /// + /// Gets the text. This property is used to filter the list of visible elements. + /// + public string Text { get; private set; } + + // Use this property if you want to show a fancy UIElement in the drop down list. + public object Content + { + get { return this.Text; } + } + + /// + /// Gets the description. + /// + public object Description + { + get { return _description; } + } + + /// + /// Gets the priority. This property is used in the selection logic. You can use it to prefer selecting those items + /// which the user is accessing most frequently. + /// + public double Priority { get { return 0; } } + + /// + /// Perform the completion. + /// + /// The text area on which completion is performed. + /// The text segment that was used by the completion window if + /// the user types (segment between CompletionWindow.StartOffset and CompletionWindow.EndOffset). + /// The EventArgs used for the insertion request. + /// These can be TextCompositionEventArgs, KeyEventArgs, MouseEventArgs, depending on how + /// the insertion was triggered. + public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) + { + textArea.Document.Replace(completionSegment, this.Text); + } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return Text; + } + } + + #endregion + + private CompletionWindow completionWindow; //Holds the auto-complete window instance. + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public ScriptEditorControl() + { + InitializeComponent(); + + textEditor.TextArea.IndentationStrategy = new ICSharpCode.AvalonEdit.Indentation.CSharp.CSharpIndentationStrategy(); + textEditor.TextArea.TextEntering += textEditor_TextArea_TextEntering; + textEditor.TextArea.TextEntered += textEditor_TextArea_TextEntered; + + this.Loaded += ScriptEditorControl_Loaded; + } + + #endregion + + #region Event Handlers + + /// + /// Handles the TextEntered event of the textEditor_TextArea control. + /// + /// The source of the event. + /// The instance containing the event data. + private void textEditor_TextArea_TextEntered(object sender, TextCompositionEventArgs e) + { + if (e.Text == ".") + { + String keyword = textEditor.TextArea.GetJustCurrentWord(); + + if (keyword != null) + { + completionWindow = new CompletionWindow(textEditor.TextArea); + completionWindow.WindowStyle = WindowStyle.None; + completionWindow.AllowsTransparency = true; + completionWindow.ResizeMode = ResizeMode.NoResize; + + IList data = completionWindow.CompletionList.CompletionData; + + bool ok = false; + + List> types = new List>(); + + types.AddRange(IntellisenseTypes); + + + if (IntellisenseTypes != null) + { + ScriptParser parser = new ScriptParser(); + + try + { + var variables = parser.ParseScript(textEditor.Text); + + foreach (var v in variables) + { + var hT = IntellisenseTypes.SingleOrDefault(x => x.Key == v.Type); + + if (hT.Value != null) + { + types.Add(new KeyValuePair(v.Name, hT.Value)); + } + } + + } + catch { } + } + + KeyValuePair type = types.LastOrDefault(x => keyword == x.Key); + + if (type.Key != null) + { + ok = true; + FillType(type.Value, data); + } + + if (ok) + { + completionWindow.Show(); + completionWindow.Closed += delegate + { + completionWindow = null; + }; + } + } + } + } + + /// + /// Handles the TextEntering event of the textEditor_TextArea control. + /// + /// The source of the event. + /// The instance containing the event data. + private void textEditor_TextArea_TextEntering(object sender, TextCompositionEventArgs e) + { + if (e.Text.Length > 0 && completionWindow != null) + { + if (!char.IsLetterOrDigit(e.Text[0])) + { + // Whenever a non-letter is typed while the completion window is open, + // insert the currently selected element. + completionWindow.CompletionList.RequestInsertion(e); + } + } + } + + /// + /// Handles the TextChanged event of the textEditor control. + /// + /// The source of the event. + /// The instance containing the event data. + private void textEditor_TextChanged(object sender, EventArgs e) + { + Text = textEditor.Text; + } + + private void ScriptEditorControl_Loaded(object sender, RoutedEventArgs e) + { + if (HighlightTypes != null) + { + Stream xshd_stream = typeof(ScriptEditorControl).Assembly.GetManifestResourceStream("Tango.SharedUI.CSharp-Mode.xshd"); + + String text = String.Empty; + + using (StreamReader reader = new StreamReader(xshd_stream)) + { + text = reader.ReadToEnd(); + } + + String code = String.Empty; + + + + foreach (var name in HighlightTypes.Select(x => x.Key)) + { + code += String.Format("{0}", name) + Environment.NewLine; + } + + text = text.Replace("@CUSTOM_TYPES@", code); + + using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(text))) + { + XmlTextReader xshd_reader = new XmlTextReader(ms); + textEditor.SyntaxHighlighting = ICSharpCode.AvalonEdit.Highlighting.Xshd.HighlightingLoader.Load(xshd_reader, ICSharpCode.AvalonEdit.Highlighting.HighlightingManager.Instance); + xshd_reader.Close(); + } + } + } + + #endregion + + #region Private Methods + + /// + /// Fills the type. + /// + /// The type. + /// The data. + private void FillType(Type type, IList data) + { + List items = new List(); + + foreach (var method in type.GetMethods().Where(x => x.IsPublic && !x.IsSpecialName)) + { + String desc = method.ReturnType.Name + " " + method.Name + "(" + String.Join(", ", method.GetParameters().Select(x => x.ParameterType.Name + " " + x.Name).ToArray()) + ")"; + items.Add(new CompletionData(method.Name, desc) { Source = ResourceHelper.GetImageFromResources("Images/pubmethod.gif") }); + } + foreach (var property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + { + String desc = property.PropertyType.Name + " " + property.Name; + items.Add(new CompletionData(property.Name, desc) { Source = ResourceHelper.GetImageFromResources("Images/pubproperty.gif") }); + } + foreach (var ev in type.GetEvents(BindingFlags.Instance | BindingFlags.Public)) + { + try + { + String desc = ev.Name + " " + "(" + String.Join(", ", ev.EventHandlerType.GetMethod("Invoke").GetParameters().Select(x => x.ParameterType.Name + " " + x.Name).ToArray()) + ")"; + items.Add(new CompletionData(ev.Name, desc) { Source = ResourceHelper.GetImageFromResources("Images/pubevent.gif") }); + } + catch { } + } + + foreach (var item in items.OrderBy(x => x.Text)) + { + data.Add(item); + } + } + + /// + /// Fills the assembly. + /// + /// The asm. + /// The data. + private void FillAssembly(Assembly asm, IList data) + { + var q = from t in asm.GetTypes() + where t.IsClass + select t; + + foreach (var type in q) + { + data.Add(new CompletionData(type.Name, "Class") { Source = ResourceHelper.GetImageFromResources("Images/pubclass.gif") }); + } + } + + #endregion + + #region Properties + + /// + /// Gets or sets the text. + /// + public String Text + { + get { return (String)GetValue(TextProperty); } + set { SetValue(TextProperty, value); } + } + public static readonly DependencyProperty TextProperty = + DependencyProperty.Register("Text", typeof(String), typeof(ScriptEditorControl), new PropertyMetadata(null, (d, e) => (d as ScriptEditorControl).OnTextChanged())); + + /// + /// Gets or sets the highlight types. + /// + public ObservableCollection> HighlightTypes + { + get { return (ObservableCollection>)GetValue(HighlightTypesProperty); } + set { SetValue(HighlightTypesProperty, value); } + } + public static readonly DependencyProperty HighlightTypesProperty = + DependencyProperty.Register("HighlightTypes", typeof(ObservableCollection>), typeof(ScriptEditorControl), new PropertyMetadata(null)); + + /// + /// Gets or sets the intellisense types. + /// + public ObservableCollection> IntellisenseTypes + { + get { return (ObservableCollection>)GetValue(IntellisenseTypesProperty); } + set { SetValue(IntellisenseTypesProperty, value); } + } + public static readonly DependencyProperty IntellisenseTypesProperty = + DependencyProperty.Register("IntellisenseTypes", typeof(ObservableCollection>), typeof(ScriptEditorControl), new PropertyMetadata(null)); + + + #endregion + + #region Virtual Methods + + /// + /// Called when the text has changed. + /// + protected virtual void OnTextChanged() + { + if (textEditor.Text != Text) + { + textEditor.Text = Text; + } + } + + /// + /// Called when the insert script command has changed. + /// + protected virtual void OnInsertScriptCommandChanged() + { + if (InsertSnippetCommand != null) + { + InsertSnippetCommand.Executed += (x, snippet) => + { + textEditor.Document.Insert(textEditor.TextArea.Caret.Offset, snippet); + }; + } + } + + #endregion + + #region Commands + + /// + /// Gets or sets the run command. + /// + public RelayCommand RunCommand + { + get { return (RelayCommand)GetValue(RunCommandProperty); } + set { SetValue(RunCommandProperty, value); } + } + public static readonly DependencyProperty RunCommandProperty = + DependencyProperty.Register("RunCommand", typeof(RelayCommand), typeof(ScriptEditorControl), new PropertyMetadata(null)); + + /// + /// Gets or sets the stop command. + /// + public RelayCommand StopCommand + { + get { return (RelayCommand)GetValue(StopCommandProperty); } + set { SetValue(StopCommandProperty, value); } + } + public static readonly DependencyProperty StopCommandProperty = + DependencyProperty.Register("StopCommand", typeof(RelayCommand), typeof(ScriptEditorControl), new PropertyMetadata(null)); + + /// + /// Gets or sets the save command. + /// + public RelayCommand SaveCommand + { + get { return (RelayCommand)GetValue(SaveCommandProperty); } + set { SetValue(SaveCommandProperty, value); } + } + public static readonly DependencyProperty SaveCommandProperty = + DependencyProperty.Register("SaveCommand", typeof(RelayCommand), typeof(ScriptEditorControl), new PropertyMetadata(null)); + + /// + /// Gets or sets the insert snippet command. + /// + public RelayCommand InsertSnippetCommand + { + get { return (RelayCommand)GetValue(InsertSnippetCommandProperty); } + set { SetValue(InsertSnippetCommandProperty, value); } + } + public static readonly DependencyProperty InsertSnippetCommandProperty = + DependencyProperty.Register("InsertSnippetCommand", typeof(RelayCommand), typeof(ScriptEditorControl), new PropertyMetadata(null, (d, e) => (d as ScriptEditorControl).OnInsertScriptCommandChanged())); + + #endregion + } + + internal static class DocumentUtils + { + private static Regex _wordRegex = new Regex(@"[^\W\d][\w]*(?<=\w)", RegexOptions.Compiled); + + public static string GetJustCurrentWord(this TextArea textArea) + { + try + { + DocumentLine line = textArea.Document.GetLineByNumber(textArea.Caret.Line); + if (line.Length == 0) + return null; + + int lineCaretPosition = textArea.Caret.Offset - line.Offset; + String l = textArea.Document.GetText(line); + + String trimmed = l.Remove(lineCaretPosition, l.Length - lineCaretPosition); + + return SplitToWords(trimmed).LastOrDefault(x => !String.IsNullOrWhiteSpace(x)); + } + catch + { + return null; + } + } + + public static List SplitToWords(String text) + { + text = text.Replace(".", " "); + text = text.Replace("(", " "); + text = text.Replace(")", " "); + text = text.Replace(",", " "); + var punctuation = text.Where(Char.IsPunctuation).Distinct().ToArray(); + var words = text.Split().Select(x => x.Trim(punctuation)); + return words.ToList(); + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs deleted file mode 100644 index 1f2856a32..000000000 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs +++ /dev/null @@ -1,269 +0,0 @@ -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; -using Tango.Core.ExtensionMethods; - -namespace Tango.SharedUI.Controls -{ - public class SearchComboBox : ComboBox - { - private TextBox _textBox; - private ListBox _listBox; - private ICollectionView _view; - - public bool IsOpened - { - 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 String SearchProperty - { - get { return (String)GetValue(SearchPropertyProperty); } - set { SetValue(SearchPropertyProperty, value); } - } - public static readonly DependencyProperty SearchPropertyProperty = - DependencyProperty.Register("SearchProperty", typeof(String), typeof(SearchComboBox), new PropertyMetadata(null)); - - public String SearchFilter - { - 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 IEnumerable ListItemsSource - { - get { return (IEnumerable)GetValue(ListItemsSourceProperty); } - set { SetValue(ListItemsSourceProperty, value); } - } - public static readonly DependencyProperty ListItemsSourceProperty = - DependencyProperty.Register("ListItemsSource", typeof(IEnumerable), typeof(SearchComboBox), new PropertyMetadata(null)); - - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - _textBox = GetTemplateChild("txt") as TextBox; - _listBox = GetTemplateChild("list") as ListBox; - _textBox.PreviewKeyDown += _textBox_KeyDown; - _listBox.PreviewKeyDown += _listBox_PreviewKeyDown; - - _listBox.PreviewMouseLeftButtonUp += _listBox_PreviewMouseLeftButtonUp; - - KeyboardNavigation.SetDirectionalNavigation(this, KeyboardNavigationMode.Once); - } - - private void _listBox_PreviewKeyDown(object sender, KeyEventArgs e) - { - if (e.Key == Key.Return) - { - IsOpened = false; - SelectedItem = _listBox.SelectedItem; - - if (SelectedValuePath.IsNotNullOrEmpty() && SelectedItem != null) - { - SelectedValue = SelectedItem.GetPropertyValueByPath(SelectedValuePath); - } - } - else if (e.Key == Key.Up && _listBox.SelectedIndex == 0) - { - _textBox.Focus(); - Keyboard.Focus(_textBox); - } - } - - private void _textBox_KeyDown(object sender, KeyEventArgs e) - { - if (e.Key == Key.Down) - { - e.Handled = true; - FocusList(); - } - } - - private void FocusList() - { - if (!String.IsNullOrWhiteSpace(SearchFilter)) - { - _listBox.SelectedIndex = 0; - } - - Keyboard.Focus(_listBox); - - if (_listBox.SelectedIndex != -1) - { - var container = _listBox.ItemContainerGenerator.ContainerFromIndex(_listBox.SelectedIndex) as UIElement; - if (container != null) - { - container.Focus(); - Keyboard.Focus(container); - } - } - - _listBox.ScrollIntoView(_listBox.SelectedItem); - } - - private void _listBox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) - { - if (_listBox.SelectedItem != null) - { - if (SelectedItem != _listBox.SelectedItem) - { - IsOpened = false; - SelectedItem = _listBox.SelectedItem; - - if (SelectedValuePath.IsNotNullOrEmpty() && SelectedItem != null) - { - SelectedValue = SelectedItem.GetPropertyValueByPath(SelectedValuePath); - } - } - } - } - - private async void OnIsOpenedChanged() - { - if (IsOpened) - { - SearchFilter = String.Empty; - _listBox.SelectedItem = SelectedItem; - _listBox.ScrollIntoView(_listBox.SelectedItem); - await Task.Delay(100); - _textBox.Focus(); - Keyboard.Focus(_textBox); - } - } - - protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue) - { - base.OnItemsSourceChanged(oldValue, newValue); - - if (ItemsSource != null) - { - ListItemsSource = ItemsSource.Cast().ToList(); - - _view = CollectionViewSource.GetDefaultView(ListItemsSource); - _view.Filter = (x) => - { - if (String.IsNullOrWhiteSpace(SearchFilter) || SearchFilter == null) return true; - - if (x != null) - { - if (!String.IsNullOrWhiteSpace(SearchProperty)) - { - var prop = x.GetType().GetProperty(SearchProperty, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); - if (prop != null) - { - String propValue = prop.GetValue(x).ToString(); - return propValue.ToLower().Contains(SearchFilter.ToLower()); - } - } - - return x.ToStringSafe().ToLower().Contains(SearchFilter.ToLower()); - } - - return false; - }; - } - } - - private void OnFilterChanged() - { - _view?.Refresh(); - - if (_listBox != null && _listBox.Items.Count > 0) - { - _listBox.ScrollIntoView(_listBox.Items[0]); - } - } - - protected override void OnPreviewKeyDown(KeyEventArgs e) - { - //base.OnPreviewKeyDown(e); - e.Handled = false; - } - - protected override void OnPreviewKeyUp(KeyEventArgs e) - { - //base.OnPreviewKeyUp(e); - e.Handled = false; - } - - protected override void OnKeyDown(KeyEventArgs e) - { - //base.OnKeyDown(e); - e.Handled = false; - } - - protected override void OnKeyUp(KeyEventArgs e) - { - //base.OnKeyUp(e); - e.Handled = false; - } - - protected override void OnPreviewMouseWheel(MouseWheelEventArgs e) - { - e.Handled = true; - - if (!_listBox.IsFocused) - { - FocusList(); - } - - if (e.Delta > 0) - { - _listBox.RaiseEvent( - new KeyEventArgs( - System.Windows.Input.Keyboard.PrimaryDevice, - PresentationSource.FromVisual(_listBox), 0, Key.Down) - { RoutedEvent = System.Windows.Input.Keyboard.KeyDownEvent }); - - _listBox.RaiseEvent( - new KeyEventArgs( - System.Windows.Input.Keyboard.PrimaryDevice, - PresentationSource.FromVisual(_listBox), 0, Key.Down) - { RoutedEvent = System.Windows.Input.Keyboard.KeyUpEvent }); - } - else - { - _listBox.RaiseEvent( - new KeyEventArgs( - System.Windows.Input.Keyboard.PrimaryDevice, - PresentationSource.FromVisual(_listBox), 0, Key.Up) - { RoutedEvent = System.Windows.Input.Keyboard.KeyDownEvent }); - - _listBox.RaiseEvent( - new KeyEventArgs( - System.Windows.Input.Keyboard.PrimaryDevice, - PresentationSource.FromVisual(_listBox), 0, Key.Up) - { RoutedEvent = System.Windows.Input.Keyboard.KeyUpEvent }); - } - //base.OnPreviewMouseWheel(e); - } - - protected override void OnMouseWheel(MouseWheelEventArgs e) - { - e.Handled = true; - //base.OnMouseWheel(e); - } - - static SearchComboBox() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(SearchComboBox), new FrameworkPropertyMetadata(typeof(SearchComboBox))); - } - } -} -- cgit v1.3.1