Files
qhmes/yy-admin-master/YY.Admin.Core/Behavior/TreeViewItemClickBehavior.cs

142 lines
5.0 KiB
C#
Raw Normal View History

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using PropertyMetadata = System.Windows.PropertyMetadata;
namespace YY.Admin.Core.Behavior
{
public class TreeViewItemClickBehavior
{
// ICommand attached property
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached(
"Command",
typeof(ICommand),
typeof(TreeViewItemClickBehavior),
new PropertyMetadata(null, OnCommandChanged));
public static void SetCommand(DependencyObject obj, ICommand value) => obj.SetValue(CommandProperty, value);
public static ICommand GetCommand(DependencyObject obj) => (ICommand)obj.GetValue(CommandProperty);
// CommandParameter attached property
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.RegisterAttached(
"CommandParameter",
typeof(object),
typeof(TreeViewItemClickBehavior),
new PropertyMetadata(null));
public static void SetCommandParameter(DependencyObject obj, object value) => obj.SetValue(CommandParameterProperty, value);
public static object GetCommandParameter(DependencyObject obj) => obj.GetValue(CommandParameterProperty);
private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TreeViewItem tvi)
{
if (e.NewValue != null && e.OldValue == null)
{
tvi.PreviewMouseLeftButtonUp += OnTreeViewItemMouseLeftButtonUp;
// 监听 TreeViewItem 展开事件Expanded
tvi.Expanded += OnTreeViewItemExpanded;
}
else if (e.NewValue == null && e.OldValue != null)
{
tvi.PreviewMouseLeftButtonUp -= OnTreeViewItemMouseLeftButtonUp;
tvi.Expanded -= OnTreeViewItemExpanded;
}
}
else
{
// 如果Style被应用到容器等也可能不是TreeViewItem延迟订阅由容器化过程处理
// 一般我们只使用在 TreeViewItem 上设置
}
}
private static void OnTreeViewItemMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
// 忽略点击展开按钮
if (e.OriginalSource is DependencyObject dep)
{
if (FindAncestor<ToggleButton>(dep) != null) return;
// 找到真正的 TreeViewItem
var tvi = FindAncestor<TreeViewItem>(dep);
if (tvi == null) return;
var cmd = GetCommand(tvi);
var param = GetCommandParameter(tvi) ?? tvi.DataContext;
// 检查是否有子项
bool hasChildren = tvi.HasItems;
// 如果有子项,则切换展开状态
if (hasChildren)
{
bool IsExpanded = !tvi.IsExpanded;
tvi.IsExpanded = IsExpanded;
// 展开
//if (IsExpanded)
//{
// // 关闭同级其它节点
// CollapseSiblings(tvi);
//}
e.Handled = true;
return;
}
if (cmd != null && cmd.CanExecute(param))
{
cmd.Execute(param);
e.Handled = true;
}
}
}
private static void OnTreeViewItemExpanded(object sender, RoutedEventArgs e)
{
if (sender is TreeViewItem tvi)
{
// 防止事件冒泡重复执行
if (e.OriginalSource != tvi)
return;
CollapseSiblings(tvi);
}
}
/// <summary>
/// 折叠同级其它 TreeViewItem
/// </summary>
private static void CollapseSiblings(TreeViewItem currentItem)
{
ItemsControl parent = ItemsControl.ItemsControlFromItemContainer(currentItem);
if (parent == null) return;
foreach (var item in parent.Items)
{
var container = parent.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
if (container != null && container != currentItem)
{
container.IsExpanded = false;
}
}
}
// 查找祖先辅助方法
private static T FindAncestor<T>(DependencyObject current) where T : DependencyObject
{
while (current != null)
{
if (current is T t) return t;
current = VisualTreeHelper.GetParent(current);
}
return null;
}
}
}