添加项目文件。
This commit is contained in:
209
Wpf.Ui.Extend/Controls/MultiTreeView/MultiTreeView.xaml.cs
Normal file
209
Wpf.Ui.Extend/Controls/MultiTreeView/MultiTreeView.xaml.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
using Wpf.Ui.Extend.Extensions;
|
||||
|
||||
namespace Wpf.Ui.Extend.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// 多选树形视图控件。
|
||||
/// </summary>
|
||||
public sealed class MultiTreeView : TreeView
|
||||
{
|
||||
|
||||
// public static readonly DependencyPropertyKey SelectedItemsPropertyKey =
|
||||
// DependencyProperty.RegisterReadOnly(
|
||||
//nameof(SelectedItems),
|
||||
// typeof(IList),
|
||||
// typeof(MultiTreeViewItem),
|
||||
// new FrameworkPropertyMetadata(null)
|
||||
// );
|
||||
|
||||
// public static readonly DependencyProperty SelectedItemsProperty = SelectedItemsPropertyKey.DependencyProperty;
|
||||
|
||||
// public IList SelectedItems
|
||||
// {
|
||||
// get { return (IList)GetValue(SelectedItemsProperty); }
|
||||
// private set { SetValue(SelectedItemsPropertyKey, value); }
|
||||
// }
|
||||
public IList SelectedItems
|
||||
{
|
||||
get { return (IList)GetValue(SelectedItemsProperty); }
|
||||
set { SetValue(SelectedItemsProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedItemsProperty =
|
||||
DependencyProperty.Register(nameof(SelectedItems), typeof(IList), typeof(MultiTreeView), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemsChanged)));
|
||||
|
||||
private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var list = e.NewValue as IList;
|
||||
//foreach (var item in list)
|
||||
//{
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
/// 在鼠标按下事件发生时调用。
|
||||
/// </summary>
|
||||
//protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
|
||||
//{
|
||||
// base.OnPreviewMouseDown(e);
|
||||
|
||||
// //// 如果点击树分支expander
|
||||
// //if (e.OriginalSource is Grid or Border or TextBlock)
|
||||
// // return;
|
||||
// var obj = e.OriginalSource as DependencyObject;
|
||||
|
||||
// var checkBox = obj.FindParent<CheckBox>();
|
||||
|
||||
// if (checkBox != null)
|
||||
// {
|
||||
// //当前点击的MultiTreeViewItem
|
||||
// var currentItem = GetTreeViewItemClicked((FrameworkElement)e.OriginalSource);
|
||||
|
||||
// if (currentItem != null)
|
||||
// {
|
||||
// SelectedItems = GetTreeViewItems(this, true).Where(d => d.IsChecked == true).ToList();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion Event Handlers
|
||||
#region Utility Methods
|
||||
|
||||
#region 重写
|
||||
|
||||
///// <summary>
|
||||
///// 准备项的容器
|
||||
///// </summary>
|
||||
///// <param name="element">控件元素</param>
|
||||
///// <param name="item">绑定的对象</param>
|
||||
//protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
|
||||
//{
|
||||
// if (item is not MultiTreeViewItem)
|
||||
// {
|
||||
// if (element is MultiTreeViewItem multiTreeViewItem && !string.IsNullOrEmpty(this.DisplayMemberPath))
|
||||
// {
|
||||
// var binding = new Binding(this.DisplayMemberPath);
|
||||
// multiTreeViewItem.SetBinding(MultiTreeViewItem.HeaderProperty, binding);
|
||||
// }
|
||||
// }
|
||||
// base.PrepareContainerForItemOverride(element, item);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项的容器。
|
||||
/// </summary>
|
||||
protected override DependencyObject GetContainerForItemOverride()
|
||||
{
|
||||
return new MultiTreeViewItem();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 确定项是否是其自己的容器。
|
||||
/// </summary>
|
||||
protected override bool IsItemItsOwnContainerOverride(object item)
|
||||
{
|
||||
return item is MultiTreeViewItem;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前被点击的MultiTreeViewItem。
|
||||
/// </summary>
|
||||
private static MultiTreeViewItem GetTreeViewItemClicked(DependencyObject sender)
|
||||
{
|
||||
while (sender is not null and not MultiTreeViewItem)
|
||||
sender = VisualTreeHelper.GetParent(sender);
|
||||
return sender as MultiTreeViewItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取树形视图的所有展开的项。
|
||||
/// </summary>
|
||||
private List<MultiTreeViewItem> GetTreeViewItems(ItemsControl parentItem, bool includeCollapsedItems, List<MultiTreeViewItem> itemList = null)
|
||||
{
|
||||
itemList ??= [];
|
||||
|
||||
for (var index = 0; index < parentItem.Items.Count; index++)
|
||||
{
|
||||
if (parentItem.ItemContainerGenerator.ContainerFromIndex(index) is not MultiTreeViewItem tvItem)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
itemList.Add(tvItem);
|
||||
if (includeCollapsedItems || tvItem.IsExpanded)
|
||||
{
|
||||
GetTreeViewItems(tvItem, includeCollapsedItems, itemList);
|
||||
}
|
||||
}
|
||||
return itemList;
|
||||
}
|
||||
|
||||
internal void NotifyMultiTreeViewItemClicked(MultiTreeViewItem multiTreeViewItem)
|
||||
{
|
||||
var selectedItems = GetTreeViewItems(this, true).Where(d => d.IsChecked == true);
|
||||
if (ItemsSource==null)
|
||||
{
|
||||
SelectedItems = selectedItems.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
//选择绑定的对象
|
||||
SelectedItems = selectedItems.Select(d => d.DataContext).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 获取两个树形视图项之间的所有项。
|
||||
///// </summary>
|
||||
//private List<MultiTreeViewItem> GetTreeViewItemRange(MultiTreeViewItem start, MultiTreeViewItem end)
|
||||
//{
|
||||
// var items = GetTreeViewItems(this, false);
|
||||
// var startIndex = items.IndexOf(start);
|
||||
// var endIndex = items.IndexOf(end);
|
||||
// var rangeStart = startIndex > endIndex || startIndex == -1 ? endIndex : startIndex;
|
||||
// var rangeCount = startIndex > endIndex ? startIndex - endIndex + 1 : endIndex - startIndex + 1;
|
||||
|
||||
// if (startIndex == -1 && endIndex == -1)
|
||||
// rangeCount = 0;
|
||||
|
||||
// else if (startIndex == -1 || endIndex == -1)
|
||||
// rangeCount = 1;
|
||||
|
||||
// return rangeCount > 0 ? items.GetRange(rangeStart, rangeCount) : new List<MultiTreeViewItem>();
|
||||
//}
|
||||
|
||||
#endregion Utility Methods
|
||||
|
||||
static MultiTreeView()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiTreeView), new FrameworkPropertyMetadata(typeof(MultiTreeView)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 MultiTreeView 类的新实例。
|
||||
/// </summary>
|
||||
//public MultiTreeView()
|
||||
//{
|
||||
//SelectedItemChanged += (sender, e) =>
|
||||
//{
|
||||
// if (e.NewValue is MultiTreeViewItem item)
|
||||
// SelectedItemChangedInternal(item);
|
||||
//};
|
||||
//}
|
||||
}
|
||||
Reference in New Issue
Block a user