using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Tango.Core.ExtensionMethods; using Tango.SharedUI.Components; using Tango.SharedUI.Controls; namespace Tango.FSE.Common.Controls { public class SelectionComboBox : Control { private bool _preventAllSelected = false; private bool _preventSelection = false; private ICollectionView _filterView; private TextBox _filterTextBox; private Popup _popup; private Button _toggle; private bool _preventToggle; public bool? AllSelected { get { return (bool?)GetValue(AllSelectedProperty); } set { SetValue(AllSelectedProperty, value); } } public static readonly DependencyProperty AllSelectedProperty = DependencyProperty.Register("AllSelected", typeof(bool?), typeof(SelectionComboBox), new PropertyMetadata(null, (d, e) => (d as SelectionComboBox).OnAllSelectedChanged())); public ISelectedObjectCollection ItemsSource { get { return (ISelectedObjectCollection)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(ISelectedObjectCollection), typeof(SelectionComboBox), new PropertyMetadata(null, (d, e) => (d as SelectionComboBox).OnItemsSourceChanged())); public String DisplayMemberPath { get { return (String)GetValue(DisplayMemberPathProperty); } set { SetValue(DisplayMemberPathProperty, value); } } public static readonly DependencyProperty DisplayMemberPathProperty = DependencyProperty.Register("DisplayMemberPath", typeof(String), typeof(SelectionComboBox), new PropertyMetadata(null)); public String Filter { get { return (String)GetValue(FilterProperty); } set { SetValue(FilterProperty, value); } } public static readonly DependencyProperty FilterProperty = DependencyProperty.Register("Filter", typeof(String), typeof(SelectionComboBox), new PropertyMetadata(null, (d, e) => (d as SelectionComboBox).OnFilterChanged())); public bool IsOpened { get { return (bool)GetValue(IsOpenedProperty); } set { SetValue(IsOpenedProperty, value); } } public static readonly DependencyProperty IsOpenedProperty = DependencyProperty.Register("IsOpened", typeof(bool), typeof(SelectionComboBox), new PropertyMetadata(false)); public override void OnApplyTemplate() { base.OnApplyTemplate(); if (!this.IsInDesignMode()) { _filterTextBox = GetTemplateChild("filterTextBox") as TextBox; _popup = GetTemplateChild("popup") as Popup; _toggle = GetTemplateChild("toggle") as Button; _toggle.Click += _toggle_Click; _popup.Opened += _popup_Opened; _popup.Closed += _popup_Closed; } } private void _toggle_Click(object sender, RoutedEventArgs e) { if (!_preventToggle) { if (!_popup.IsOpen) { _popup.IsOpen = true; } else { _popup.IsOpen = false; } } _preventToggle = false; } private async void _popup_Closed(object sender, EventArgs e) { _preventToggle = true; await Task.Delay(100); _preventToggle = false; } private void _popup_Opened(object sender, EventArgs e) { _filterTextBox.Focus(); } private void OnItemsSourceChanged() { if (ItemsSource != null) { _filterView = CollectionViewSource.GetDefaultView(ItemsSource); _filterView.Filter = ApplyFilter; ItemsSource.SelectionChanged += ItemsSource_SelectionChanged; } } private void ItemsSource_SelectionChanged(object sender, EventArgs e) { if (!_preventSelection) { if (ItemsSource.GetItems().All(x => x.IsSelected)) { _preventAllSelected = true; AllSelected = true; } else if (ItemsSource.GetItems().All(x => !x.IsSelected)) { _preventAllSelected = true; AllSelected = false; } else { _preventAllSelected = true; AllSelected = null; } } _preventAllSelected = false; } private void OnAllSelectedChanged() { _preventSelection = true; if (!_preventAllSelected && AllSelected != null) { foreach (var item in ItemsSource.GetItems()) { item.IsSelected = AllSelected.Value; } } _preventSelection = false; } private void OnFilterChanged() { _filterView?.Refresh(); } private bool ApplyFilter(object obj) { if (Filter.IsNotNullOrEmpty()) { if (obj is SelectedObject selectedObject) { try { return selectedObject.Data.GetPropertyValueByPath(DisplayMemberPath).ToStringSafe().ToLower().Contains(Filter.ToLower()); } catch { return true; } } else { return false; } } else { return true; } } static SelectionComboBox() { DefaultStyleKeyProperty.OverrideMetadata(typeof(SelectionComboBox), new FrameworkPropertyMetadata(typeof(SelectionComboBox))); } } }