Files
ShrlAlgoToolkit/WPFluent/Controls/CheckComboBox/CheckComboBox.cs
ShrlAlgo 4d35cadb56 更新
2025-07-11 09:20:23 +08:00

301 lines
9.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using WPFluent.Extensions;
namespace WPFluent.Controls
{
/// <summary>
/// 通过该类,对绑定的集合->重新创建为CheckComboBoxItem->应用默认样式
/// </summary>
public class CheckComboBox : ComboBoxEx
{
#region Internal
/// <summary>
/// 行选中
/// </summary>
/// <param name="item"></param>
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 System.Windows.Controls.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));
/// <summary>
/// 内容
/// </summary>
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));
/// <summary>
/// 值
/// </summary>
public string Value { get { return (string)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } }
#region SelectedObjList
[Bindable(true), Description("获取或者设置当前勾选项列表")]
public ObservableCollection<object> SelectedObjList
{
get { return (ObservableCollection<object>)GetValue(SelectedObjListProperty); }
set { SetValue(SelectedObjListProperty, value); }
}
public static readonly DependencyProperty SelectedObjListProperty =
DependencyProperty.Register(
nameof(SelectedObjList),
typeof(ObservableCollection<object>),
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<string> SelectedStrList
{
get { return (ObservableCollection<string>)GetValue(SelectedStrListProperty); }
set { SetValue(SelectedStrListProperty, value); }
}
public static readonly DependencyProperty SelectedStrListProperty =
DependencyProperty.Register(
nameof(SelectedStrList),
typeof(ObservableCollection<string>),
typeof(CheckComboBox));
#endregion
/// <summary>
/// 获取或者设置最多显示的选中个数
/// </summary>
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 System.Windows.Controls.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([' '])
.TrimEnd([',']);
Value = SelectedStrList.Aggregate(string.Empty, (current, p) => $"{current}{p},")
.TrimEnd([',']);
}
#endregion
#region Event Implement Function
/// <summary>
/// 每次Open回显数据不太好先这么处理
/// </summary>
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;
}
}
/// <summary>
/// 搜索关键字
/// </summary>
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
}
}