using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using Wpf.Ui.Extend.Extensions; namespace Wpf.Ui.Extend.Controls { /// /// 通过该类,对绑定的集合->重新创建为CheckComboBoxItem->应用默认样式 /// public class CheckComboBox : ComboBoxEx { #region PrivateProperty private ContentPresenter PART_ContentSite; private TextBox PART_FilterTextBox; private ICollectionView view; private Popup PART_Popup; private bool popupIsFirstOpen; #endregion #region DependencyProperty public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(string), typeof(CheckComboBox), new PropertyMetadata(string.Empty)); /// /// 内容 /// public string Content { get { return (string)GetValue(ContentProperty); } set { SetValue(ContentProperty, value); } } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(string), typeof(CheckComboBox), new PropertyMetadata(string.Empty)); /// /// 值 /// public string Value { get { return (string)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } #region SelectedObjList [Bindable(true), Description("获取或者设置当前勾选项列表")] public ObservableCollection SelectedObjList { get { return (ObservableCollection)GetValue(SelectedObjListProperty); } set { SetValue(SelectedObjListProperty, value); } } public static readonly DependencyProperty SelectedObjListProperty = DependencyProperty.Register(nameof(SelectedObjList), typeof(ObservableCollection), typeof(CheckComboBox), new PropertyMetadata(null, OnSelectedObjListChanged)); private static void OnSelectedObjListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var checkComboBox = d as CheckComboBox; if (checkComboBox.ItemsSource != null) checkComboBox.SetCheckComboBoxValueAndContent(); } #endregion #region SelectedStrList public ObservableCollection SelectedStrList { get { return (ObservableCollection)GetValue(SelectedStrListProperty); } set { SetValue(SelectedStrListProperty, value); } } public static readonly DependencyProperty SelectedStrListProperty = DependencyProperty.Register(nameof(SelectedStrList), typeof(ObservableCollection), typeof(CheckComboBox)); #endregion /// /// 获取或者设置最多显示的选中个数 /// public int MaxShowNumber { get { return (int)GetValue(MaxShowNumberProperty); } set { SetValue(MaxShowNumberProperty, value); } } public static readonly DependencyProperty MaxShowNumberProperty = DependencyProperty.Register(nameof(MaxShowNumber), typeof(int), typeof(CheckComboBox), new PropertyMetadata(3)); #endregion #region Constructors static CheckComboBox() { DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckComboBox), new FrameworkPropertyMetadata(typeof(CheckComboBox))); } public CheckComboBox() { this.SelectedObjList = []; this.SelectedStrList = []; } #endregion #region Override public override void OnApplyTemplate() { base.OnApplyTemplate(); if (this.PART_FilterTextBox != null) { this.PART_FilterTextBox.TextChanged -= PART_FilterTextBox_TextChanged; } if (PART_Popup != null) { this.PART_Popup.Opened -= PART_Popup_Opened; } this.PART_ContentSite = this.GetTemplateChild("PART_ContentSite") as ContentPresenter; this.PART_FilterTextBox = this.GetTemplateChild("PART_FilterTextBox") as TextBox; this.PART_Popup = this.GetTemplateChild("PART_Popup") as Popup; if (this.PART_FilterTextBox != null) { this.PART_FilterTextBox.TextChanged += PART_FilterTextBox_TextChanged; } view = CollectionViewSource.GetDefaultView(this.ItemsSource); if (PART_Popup != null) { this.PART_Popup.Opened += PART_Popup_Opened; } this.Init(); } protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { if (item is not CheckComboBoxItem) { if (element is CheckComboBoxItem checkComboBoxItem && !string.IsNullOrEmpty(this.DisplayMemberPath)) { var binding = new Binding(this.DisplayMemberPath); checkComboBoxItem.SetBinding(CheckComboBoxItem.ContentProperty, binding); } } base.PrepareContainerForItemOverride(element, item); } protected override DependencyObject GetContainerForItemOverride() { return new CheckComboBoxItem(); } protected override bool IsItemItsOwnContainerOverride(object item) { return (item is CheckComboBoxItem); } #endregion #region PrivateFunction private void Init() { this.popupIsFirstOpen = true; if (this.SelectedObjList != null) { foreach (var obj in this.SelectedObjList) { if (string.IsNullOrWhiteSpace(this.DisplayMemberPath)) { this.SelectedStrList.Add(obj.ToString()); } else { this.SelectedStrList.Add(obj.GetPropertyValue(this.DisplayMemberPath).ToString()); } } } this.SetCheckComboBoxValueAndContent(); } private void SetCheckComboBoxValueAndContent() { if (SelectedObjList == null || SelectedObjList.Count <= 0) SelectedStrList = []; if (this.SelectedStrList == null) return; this.Content = this.SelectedStrList.Count > this.MaxShowNumber ? $"选中{this.SelectedStrList.Count}个" : this.SelectedStrList.Aggregate("", (current, p) => current + (p + ", ")).TrimEnd(new char[] { ' ' }).TrimEnd(new char[] { ',' }); this.Value = this.SelectedStrList.Aggregate("", (current, p) => current + (p + ",")).TrimEnd(new char[] { ',' }); } #endregion #region Internal /// /// 行选中 /// /// internal void NotifyCheckComboBoxItemClicked(CheckComboBoxItem item) { var itemContent = Convert.ToString(item.Content); this.SelectedStrList ??= []; this.SelectedObjList ??= []; if (item.IsSelected) { if (!this.SelectedStrList.Contains(item.Content)) { this.SelectedStrList.Add(itemContent); } if (!this.SelectedObjList.Contains(item.DataContext)) { this.SelectedObjList.Add(item.DataContext); } } else { if (this.SelectedStrList.Contains(itemContent)) { this.SelectedStrList.Remove(itemContent); } if (this.SelectedObjList.Contains(item.DataContext)) { this.SelectedObjList.Remove(item.DataContext); } } this.SetCheckComboBoxValueAndContent(); } #endregion #region Event Implement Function /// /// 每次Open回显数据不太好,先这么处理 /// private void PART_Popup_Opened(object sender, EventArgs e) { if (!this.popupIsFirstOpen) return; this.popupIsFirstOpen = false; if (this.ItemsSource == null || this.SelectedObjList == null) return; foreach (var obj in this.SelectedObjList) { if (this.ItemContainerGenerator.ContainerFromItem(obj) is CheckComboBoxItem checkComboBoxItem) checkComboBoxItem.IsSelected = true; } } /// /// 搜索关键字 /// private void PART_FilterTextBox_TextChanged(object sender, TextChangedEventArgs e) { if (this.PART_FilterTextBox == null || view == null) return; view.Filter += (o) => { var value = Convert.ToString(o.GetPropertyValue(this.DisplayMemberPath)).ToLower(); return value.Contains(this.PART_FilterTextBox.Text); }; foreach (var obj in this.SelectedObjList) { if (this.ItemContainerGenerator.ContainerFromItem(obj) is CheckComboBoxItem checkComboBoxItem) checkComboBoxItem.IsSelected = true; } } #endregion } }