2021-07-23 09:42:22 +08:00
|
|
|
|
using System;
|
2022-12-12 22:33:17 +08:00
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
|
using System.ComponentModel;
|
2021-07-23 09:42:22 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
|
|
2022-12-12 22:33:17 +08:00
|
|
|
|
namespace AIStudio.Wpf.DiagramDesigner.Controls
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <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 =
|
2022-12-01 23:12:13 +08:00
|
|
|
|
DependencyProperty.Register(nameof(ItemsSource), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null,
|
2021-07-23 09:42:22 +08:00
|
|
|
|
new PropertyChangedCallback(MultiSelectComboBox.OnItemsSourceChanged)));
|
|
|
|
|
|
|
|
|
|
|
|
public static readonly DependencyProperty SelectedItemsProperty =
|
2022-12-01 23:12:13 +08:00
|
|
|
|
DependencyProperty.Register(nameof(SelectedItems), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null,
|
2021-07-23 09:42:22 +08:00
|
|
|
|
new PropertyChangedCallback(MultiSelectComboBox.OnSelectedItemsChanged)));
|
|
|
|
|
|
|
|
|
|
|
|
public static readonly DependencyProperty SelectedValuesProperty =
|
2022-12-01 23:12:13 +08:00
|
|
|
|
DependencyProperty.Register(nameof(SelectedValues), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null,
|
2021-07-23 09:42:22 +08:00
|
|
|
|
new PropertyChangedCallback(MultiSelectComboBox.OnSelectedValuesChanged)));
|
|
|
|
|
|
|
|
|
|
|
|
public static readonly DependencyProperty TextProperty =
|
2022-12-01 23:12:13 +08:00
|
|
|
|
DependencyProperty.Register(nameof(Text), typeof(string), typeof(MultiSelectComboBox), new UIPropertyMetadata(string.Empty));
|
2021-07-23 09:42:22 +08:00
|
|
|
|
|
|
|
|
|
|
public static readonly DependencyProperty DefaultTextProperty =
|
2022-12-01 23:12:13 +08:00
|
|
|
|
DependencyProperty.Register(nameof(DefaultText), typeof(string), typeof(MultiSelectComboBox), new UIPropertyMetadata(string.Empty));
|
2021-07-23 09:42:22 +08:00
|
|
|
|
|
|
|
|
|
|
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();
|
2022-12-02 08:44:40 +08:00
|
|
|
|
control.SelectNodes();
|
|
|
|
|
|
control.SetText();
|
2021-07-23 09:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2022-12-04 23:07:20 +08:00
|
|
|
|
Node node = _nodeList.FirstOrDefault(i => i.Object != null && i.Object.ToString() != "All" && i.Object.GetPropertyValue(SelectedValuePath)?.ToString() == item?.ToString());
|
2021-07-23 09:42:22 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2022-12-02 08:44:40 +08:00
|
|
|
|
//不使用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")
|
2021-07-23 09:42:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
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));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|