using WPFluent.Extensions; using System; using System.Linq; namespace WPFluent.Controls; public class MultiTreeViewItem : System.Windows.Controls.TreeViewItem { public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register( nameof(IsChecked), typeof(bool?), typeof(MultiTreeViewItem), new PropertyMetadata(false, new PropertyChangedCallback(OnIsCheckedChanged))); static MultiTreeViewItem() { DefaultStyleKeyProperty.OverrideMetadata( typeof(MultiTreeViewItem), new FrameworkPropertyMetadata(typeof(MultiTreeViewItem))); IsExpandedProperty.OverrideMetadata(typeof(MultiTreeViewItem), new FrameworkPropertyMetadata(true)); } private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var currentChildren = d.FindVisualChildren(); if(e.NewValue == e.OldValue) { return; } if(d is MultiTreeViewItem currentItem) { currentItem?.ParentMultiTreeView?.NotifyMultiTreeViewItemClicked(currentItem); foreach(var item in currentItem.FindVisualChildren()) { if(e.NewValue != null) { item.IsChecked = (bool)e.NewValue; } } } var parent = d.FindParent(); if(parent != null) { var children = parent.FindVisualChildren(); if(children.All(d => d.IsChecked == true)) { parent.IsChecked = true; } else { parent.IsChecked = children.All(d => d.IsChecked == false) ? false : null; } } } private MultiTreeView ParentMultiTreeView { //get { return ItemsControl.ItemsControlFromItemContainer(this) as MultiTreeView; } get { return this.FindParent(); } } /// /// 获取项的容器。 /// protected override DependencyObject GetContainerForItemOverride() { return new MultiTreeViewItem(); } /// /// 确定项是否是其自己的容器。 /// protected override bool IsItemItsOwnContainerOverride(object item) { return item is MultiTreeViewItem; } public bool? IsChecked { get { return (bool?)GetValue(IsCheckedProperty); } set { SetValue(IsCheckedProperty, value); } } }