using System; using System.Collections; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; namespace AIStudio.Wpf.DiagramDesigner.Controls { /// <summary> /// Interaction logic for MultiSelectComboBox.xaml /// </summary> public partial class MultiSelectComboBox : UserControl { private ObservableCollection<Node> _nodeList; public MultiSelectComboBox() { InitializeComponent(); _nodeList = new ObservableCollection<Node>(); } #region Dependency Properties public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(nameof(ItemsSource), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(MultiSelectComboBox.OnItemsSourceChanged))); public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register(nameof(SelectedItems), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(MultiSelectComboBox.OnSelectedItemsChanged))); public static readonly DependencyProperty SelectedValuesProperty = DependencyProperty.Register(nameof(SelectedValues), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(MultiSelectComboBox.OnSelectedValuesChanged))); public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(MultiSelectComboBox), new UIPropertyMetadata(string.Empty)); public static readonly DependencyProperty DefaultTextProperty = DependencyProperty.Register(nameof(DefaultText), typeof(string), typeof(MultiSelectComboBox), new UIPropertyMetadata(string.Empty)); public string DisplayMemberPath { get; set; } public string SelectedValuePath { get; set; } public IList ItemsSource { get { return (IList)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } public IList SelectedItems { get { return (IList)GetValue(SelectedItemsProperty); } set { SetValue(SelectedItemsProperty, value); } } public IList SelectedValues { get { return (IList)GetValue(SelectedValuesProperty); } set { SetValue(SelectedValuesProperty, value); } } public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public string DefaultText { get { return (string)GetValue(DefaultTextProperty); } set { SetValue(DefaultTextProperty, value); } } #endregion #region Events private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MultiSelectComboBox control = (MultiSelectComboBox)d; control.DisplayInControl(); control.SelectNodes(); control.SetText(); } private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MultiSelectComboBox control = (MultiSelectComboBox)d; control.SelectNodes(); control.SetText(); } private static void OnSelectedValuesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MultiSelectComboBox control = (MultiSelectComboBox)d; control.SelectNodes(); control.SetText(); } private void CheckBox_Click(object sender, RoutedEventArgs e) { CheckBox clickedBox = (CheckBox)sender; if (clickedBox.Content.ToString() == "All") { if (clickedBox.IsChecked.Value) { foreach (Node node in _nodeList) { node.IsSelected = true; } } else { foreach (Node node in _nodeList) { node.IsSelected = false; } } } else { int _selectedCount = 0; foreach (Node s in _nodeList) { if (s.IsSelected && s.Object.ToString() != "All") _selectedCount++; } if (_selectedCount == _nodeList.Count - 1) _nodeList.FirstOrDefault(i => i.Object.ToString() == "All").IsSelected = true; else _nodeList.FirstOrDefault(i => i.Object.ToString() == "All").IsSelected = false; } SetSelectedItems(); SetText(); } #endregion #region Methods private void SelectNodes() { if (SelectedItems != null) { foreach (var item in SelectedItems) { Node node = _nodeList.FirstOrDefault(i => i.Object == item); if (node != null) node.IsSelected = true; } } else if (SelectedValues != null) { foreach (var item in SelectedValues) { Node node = _nodeList.FirstOrDefault(i => i.Object != null && i.Object.ToString() != "All" && i.Object.GetPropertyValue(SelectedValuePath)?.ToString() == item?.ToString()); if (node != null) node.IsSelected = true; } } } private void SetSelectedItems() { if (SelectedItems != null) { SelectedItems.Clear(); foreach (Node node in _nodeList) { if (node.IsSelected && node.Object.ToString() != "All") { if (this.ItemsSource.Count > 0) { if (SelectedItems != null) { SelectedItems.Add(node.Object); } } } } } if (SelectedValues != null) { SelectedValues.Clear(); foreach (Node node in _nodeList) { if (node.IsSelected && node.Object.ToString() != "All") { if (this.ItemsSource.Count > 0) { if (SelectedValues != null) { SelectedValues.Add(node.Object.GetPropertyValue(SelectedValuePath)); } } } } } } private void DisplayInControl() { _nodeList.Clear(); if (this.ItemsSource.Count > 0) _nodeList.Add(new Node("All", DisplayMemberPath)); foreach (var item in this.ItemsSource) { Node node = new Node(item, DisplayMemberPath); _nodeList.Add(node); } MultiSelectCombo.ItemsSource = _nodeList; } private void SetText() { StringBuilder displayText = new StringBuilder(); foreach (Node s in _nodeList) { //不使用ALl来显示 //if (s.IsSelected == true && s.Object.ToString() == "All") //{ // displayText = new StringBuilder(); // displayText.Append("All"); // break; //} //else if (s.IsSelected == true && s.Object.ToString() != "All") { displayText.Append(s.Object); displayText.Append(','); } } this.Text = displayText.ToString().TrimEnd(new char[] { ',' }); // set DefaultText if nothing else selected if (string.IsNullOrEmpty(this.Text)) { this.Text = this.DefaultText; } } #endregion } public class Node : INotifyPropertyChanged { #region ctor public Node(object obj, string displayMemberPath) { Object = obj; if (!string.IsNullOrEmpty(displayMemberPath) && Object.ContainsProperty(displayMemberPath)) Title = Object.GetPropertyValue(displayMemberPath).ToString(); else Title = obj.ToString(); } #endregion #region Properties private object _object; public object Object { get { return _object; } set { _object = value; NotifyPropertyChanged("Object"); } } private string _title; public string Title { get { return _title; } set { _title = value; NotifyPropertyChanged("Title"); } } private bool _isSelected; public bool IsSelected { get { return _isSelected; } set { _isSelected = value; NotifyPropertyChanged("IsSelected"); } } #endregion public event PropertyChangedEventHandler PropertyChanged; protected void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } }