Files
Ramitta-lib/Ramitta/winTreeList.xaml.cs
XerolySkinner 624125ec7b Ramitta
我是米塔更新
2025-08-29 14:57:55 +08:00

428 lines
13 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.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Xml.Linq;
namespace Ramitta
{
public partial class winTreeList : UserControl
{
public winTreeList()
{
InitializeComponent();
Nodes = new ObservableCollection<TreeNode>();
}
#region
/// <summary>
/// 获取或设置树形列表的节点集合
/// </summary>
public ObservableCollection<TreeNode> Nodes
{
get { return (ObservableCollection<TreeNode>)GetValue(NodesProperty); }
set { SetValue(NodesProperty, value); }
}
public static readonly DependencyProperty NodesProperty =
DependencyProperty.Register("Nodes", typeof(ObservableCollection<TreeNode>),
typeof(winTreeList), new PropertyMetadata(null, OnNodesChanged));
private static void OnNodesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (winTreeList)d;
control.treeView.ItemsSource = control.Nodes;
}
#endregion
#region
#region
public LabelTreeNode AddLabelNode(string text, TreeNode parent = null)
{
var node = new LabelTreeNode { Text = text };
AddNode(node, parent);
return node;
}
public CheckboxTreeNode AddCheckboxNode(string text, string? tag=null, bool isChecked = false, TreeNode parent = null)
{
var node = new CheckboxTreeNode {
Text = text,
IsChecked = isChecked,
Tag = tag ?? text };
AddNode(node, parent);
return node;
}
public ComboboxTreeNode AddComboboxNode(string text, string[]? item=null, TreeNode parent = null)
{
var node = new ComboboxTreeNode {
Text = text,
ComboBoxItems = new ObservableCollection<string>(item ?? []),
};
AddNode(node, parent);
return node;
}
#endregion
#region
public TreeNode? FindNode(IEnumerable<TreeNode> nodes, List<string> key) {
if(key.Count == 0) return null;
foreach (var node in nodes)
{
if (node is TreeNode obj &&
obj.Text == key[0] &&
key.Count==1)
{
// 最后的层级,且符合指标的第一个值
return obj;
}
var foundNode = FindNode(node.Children, key.Skip(1).ToList());
if (foundNode != null)
{
return foundNode;
}
}
return null;
}
public List<TreeNode> FindAllTreeNodes(IEnumerable<TreeNode> nodes, string key, Type? targetType = null)
{
List<TreeNode> foundNodes = new List<TreeNode>();
foreach (var node in nodes)
{
// 检查当前节点是否匹配
if (node.Text == key && (targetType == null || targetType.IsAssignableFrom(node.GetType())))
{
foundNodes.Add(node);
}
// 递归查找子节点
foundNodes.AddRange(FindAllTreeNodes(node.Children, key, targetType));
}
return foundNodes;
}
/// <summary>
/// 获取所有被勾选的Checkbox节点的Tag
/// </summary>
/// <param name="nodes">当前节点集合</param>
/// <returns>被勾选Checkbox节点的Tag列表</returns>
public List<string> GetCheckedCheckboxTags(IEnumerable<TreeNode> nodes)
{
var tags = new List<string>();
foreach (var node in nodes)
{
if (node is CheckboxTreeNode checkboxNode && checkboxNode.IsChecked)
{
tags.Add(checkboxNode.Tag);
}
// 递归查找子节点
tags.AddRange(GetCheckedCheckboxTags(node.Children));
}
return tags;
}
/// <summary>
/// 获取所有被勾选的Checkbox节点的Tag
/// </summary>
/// <param name="nodes">当前节点集合</param>
/// <returns>被勾选Checkbox节点的Tag列表</returns>
public List<string> GetNoCheckedCheckboxTags(IEnumerable<TreeNode> nodes)
{
var tags = new List<string>();
foreach (var node in nodes)
{
if (node is CheckboxTreeNode checkboxNode && checkboxNode.IsChecked != true)
{
tags.Add(checkboxNode.Tag);
}
// 递归查找子节点
tags.AddRange(GetCheckedCheckboxTags(node.Children));
}
return tags;
}
public List<CheckboxTreeNode> GetNoCheckBoxNodes(bool check)
{
return GetAllNodes().OfType<CheckboxTreeNode>().
Where(n =>
(check ? n.IsChecked : !n.IsChecked)
).ToList();
}
/// <summary>
/// 获取指定Label节点下所有被勾选的Checkbox节点的Tag列表
/// </summary>
/// <param name="labelNodeName">Label节点的名称</param>
/// <returns>被勾选Checkbox节点的Tag列表</returns>
public List<string> GetCheckboxTagsUnderLabelNode(string labelNodeName)
{
var tags = new List<string>();
List<TreeNode> getTreeNode = FindAllTreeNodes(Nodes, labelNodeName, typeof(LabelTreeNode));
var labelNode = getTreeNode.Count != 0 ? getTreeNode[0] : null;
if (labelNode != null)
{
// 如果找到了Label节点搜索其子节点
tags.AddRange(GetCheckedCheckboxTags(labelNode.Children));
}
return tags;
}
public xTreeNode? FindTreeNodes<xTreeNode>(IEnumerable<TreeNode>? nodes, string key)
where xTreeNode : class
{
if (nodes == null) nodes = Nodes;
foreach (var node in nodes)
{
// 检查当前节点是否匹配
if (node.Text == key)
{
return node as xTreeNode;
}
if (node.Children == null) return null;
//FindTreeNodes<xTreeNode>(node.Children, key);
}
return null;
// throw new NotImplementedException($"方法:{System.Reflection.MethodBase.GetCurrentMethod()?.Name}的targetNode为空");
}
public xControl? Find<xTreeNode, xControl>(IEnumerable<TreeNode>? nodes, string key)
where xTreeNode : class
where xControl : DependencyObject
{
if (nodes == null) nodes = Nodes;
xTreeNode targetNode = FindTreeNodes<xTreeNode>(nodes, key);
if (targetNode == null)
throw new NotImplementedException($"方法:{System.Reflection.MethodBase.GetCurrentMethod()?.Name}的targetNode为空");
return To<xTreeNode, xControl>(targetNode);
}
public xControl? To<xTreeNode, xControl>(xTreeNode node)
where xTreeNode : class
where xControl : DependencyObject
{
var treeViewItem = FindTreeViewItem<xTreeNode>(treeView, node);
if (treeViewItem != null)
{
xControl xCtrl = FindVisualChild<xControl>(treeViewItem);
if (xCtrl != null)
{
return xCtrl;
}
}
throw new NotImplementedException(
$"方法:{System.Reflection.MethodBase.GetCurrentMethod()?.Name}的{treeViewItem}为空");
}
private TreeViewItem FindTreeViewItem<T>(ItemsControl container, T xTreeNode) where T : class
{
for (int i = 0; i < container.Items.Count; i++)
{
TreeViewItem item = container.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem;
if (item != null)
{
if (item.DataContext == xTreeNode)
{
return item;
}
TreeViewItem childItem = FindTreeViewItem<T>(item, xTreeNode);
if (childItem != null)
{
return childItem;
}
}
}
return null;
}
private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is T)
{
return (T)child;
}
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
{
return childOfChild;
}
}
return null;
}
#endregion
#region
#endregion
#region
public void Clear()
{
Nodes.Clear();
}
public void ExpandAll()
{
foreach (var node in Nodes)
{
ExpandNode(node);
}
}
public void CollapseAll()
{
foreach (var node in Nodes)
{
CollapseNode(node);
}
}
#endregion
#endregion
#region
private void AddNode(TreeNode node, TreeNode parent)
{
if (parent == null)
{
Nodes.Add(node);
}
else
{
parent.Children.Add(node);
}
}
private IEnumerable<TreeNode> GetAllNodes()
{
return GetAllNodes(Nodes);
}
private IEnumerable<TreeNode> GetAllNodes(IEnumerable<TreeNode> nodes)
{
foreach (var node in nodes)
{
yield return node;
foreach (var child in GetAllNodes(node.Children))
{
yield return child;
}
}
}
private void ExpandNode(TreeNode node)
{
var container = treeView.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem;
if (container != null)
{
container.IsExpanded = true;
}
foreach (var child in node.Children)
{
ExpandNode(child);
}
}
private void CollapseNode(TreeNode node)
{
var container = treeView.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem;
if (container != null)
{
container.IsExpanded = false;
}
foreach (var child in node.Children)
{
CollapseNode(child);
}
}
#endregion
}
#region
public abstract class TreeNode
{
public TreeNode()
{
Children = new ObservableCollection<TreeNode>();
}
public string Text { get; set; }
public ObservableCollection<TreeNode> Children { get; set; }
}
/// <summary>
/// Label类型的树节点
/// </summary>
public class LabelTreeNode : TreeNode
{
}
/// <summary>
/// Label类型的树节点
/// </summary>
public class ComboboxTreeNode : TreeNode
{
public string SelectedItem { get; set; }
public ObservableCollection<string> ComboBoxItems { get; set; } = new ObservableCollection<string>();
}
/// <summary>
/// Checkbox类型的树节点
/// </summary>
public class CheckboxTreeNode : TreeNode
{
public string Tag { get; set; }
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set
{
if (_isChecked != value)
{
_isChecked = value;
}
}
}
}
#endregion
}