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

142 lines
5.0 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.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;
}
}
}