using WPFluent.Extensions; using System; using System.Collections.ObjectModel; using System.Linq; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; namespace WPFluent.Controls { /// /// 通过该类,对绑定的集合->重新创建为CheckComboBoxItem->应用默认样式 /// public class CheckComboBox : ComboBoxEx { #region Internal /// /// 行选中 /// /// internal void NotifyCheckComboBoxItemClicked(CheckComboBoxItem item) { var itemContent = Convert.ToString(item.Content); SelectedStrList ??= []; SelectedObjList ??= []; if(item.IsSelected) { if(!SelectedStrList.Contains(item.Content)) { SelectedStrList.Add(itemContent); } if(!SelectedObjList.Contains(item.DataContext)) { SelectedObjList.Add(item.DataContext); } } else { if(SelectedStrList.Contains(itemContent)) { SelectedStrList.Remove(itemContent); } if(SelectedObjList.Contains(item.DataContext)) { SelectedObjList.Remove(item.DataContext); } } SetCheckComboBoxValueAndContent(); } #endregion #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() { SelectedObjList = []; SelectedStrList = []; } #endregion #region Override public override void OnApplyTemplate() { base.OnApplyTemplate(); if(PART_FilterTextBox != null) { PART_FilterTextBox.TextChanged -= PART_FilterTextBox_TextChanged; } if(PART_Popup != null) { PART_Popup.Opened -= PART_Popup_Opened; } PART_ContentSite = GetTemplateChild("PART_ContentSite") as ContentPresenter; PART_FilterTextBox = GetTemplateChild("PART_FilterTextBox") as TextBox; PART_Popup = GetTemplateChild("PART_Popup") as Popup; if(PART_FilterTextBox != null) { PART_FilterTextBox.TextChanged += PART_FilterTextBox_TextChanged; } view = CollectionViewSource.GetDefaultView(ItemsSource); if(PART_Popup != null) { PART_Popup.Opened += PART_Popup_Opened; } Init(); } protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { if(item is not CheckComboBoxItem) { if(element is CheckComboBoxItem checkComboBoxItem && !string.IsNullOrEmpty(DisplayMemberPath)) { var binding = new Binding(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() { popupIsFirstOpen = true; if(SelectedObjList != null) { foreach(var obj in SelectedObjList) { if(string.IsNullOrWhiteSpace(DisplayMemberPath)) { SelectedStrList.Add(obj.ToString()); } else { SelectedStrList.Add(obj.GetPropertyValue(DisplayMemberPath).ToString()); } } } SetCheckComboBoxValueAndContent(); } private void SetCheckComboBoxValueAndContent() { if(SelectedObjList == null || SelectedObjList.Count <= 0) SelectedStrList = []; if(SelectedStrList == null) return; Content = SelectedStrList.Count > MaxShowNumber ? $"选中{SelectedStrList.Count}个" : SelectedStrList.Aggregate(string.Empty, (current, p) => $"{current}{p}, ") .TrimEnd(new char[] { ' ' }) .TrimEnd(new char[] { ',' }); Value = SelectedStrList.Aggregate(string.Empty, (current, p) => $"{current}{p},") .TrimEnd(new char[] { ',' }); } #endregion #region Event Implement Function /// /// 每次Open回显数据不太好,先这么处理 /// private void PART_Popup_Opened(object sender, EventArgs e) { if(!popupIsFirstOpen) return; popupIsFirstOpen = false; if(ItemsSource == null || SelectedObjList == null) return; foreach(var obj in SelectedObjList) { if(ItemContainerGenerator.ContainerFromItem(obj) is CheckComboBoxItem checkComboBoxItem) checkComboBoxItem.IsSelected = true; } } /// /// 搜索关键字 /// private void PART_FilterTextBox_TextChanged(object sender, TextChangedEventArgs e) { if(PART_FilterTextBox == null || view == null) return; view.Filter += (o) => { var value = Convert.ToString(o.GetPropertyValue(DisplayMemberPath)).ToLower(); return value.Contains(PART_FilterTextBox.Text); }; foreach(var obj in SelectedObjList) { if(ItemContainerGenerator.ContainerFromItem(obj) is CheckComboBoxItem checkComboBoxItem) checkComboBoxItem.IsSelected = true; } } #endregion } }