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(); } #region 公共属性 /// /// 获取或设置树形列表的节点集合 /// public ObservableCollection Nodes { get { return (ObservableCollection)GetValue(NodesProperty); } set { SetValue(NodesProperty, value); } } public static readonly DependencyProperty NodesProperty = DependencyProperty.Register("Nodes", typeof(ObservableCollection), 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(item ?? []), }; AddNode(node, parent); return node; } #endregion #region 查 public TreeNode? FindNode(IEnumerable nodes, List 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 FindAllTreeNodes(IEnumerable nodes, string key, Type? targetType = null) { List foundNodes = new List(); 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; } /// /// 获取所有被勾选的Checkbox节点的Tag /// /// 当前节点集合 /// 被勾选Checkbox节点的Tag列表 public List GetCheckedCheckboxTags(IEnumerable nodes) { var tags = new List(); foreach (var node in nodes) { if (node is CheckboxTreeNode checkboxNode && checkboxNode.IsChecked) { tags.Add(checkboxNode.Tag); } // 递归查找子节点 tags.AddRange(GetCheckedCheckboxTags(node.Children)); } return tags; } /// /// 获取所有被勾选的Checkbox节点的Tag /// /// 当前节点集合 /// 被勾选Checkbox节点的Tag列表 public List GetNoCheckedCheckboxTags(IEnumerable nodes) { var tags = new List(); 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 GetNoCheckBoxNodes(bool check) { return GetAllNodes().OfType(). Where(n => (check ? n.IsChecked : !n.IsChecked) ).ToList(); } /// /// 获取指定Label节点下所有被勾选的Checkbox节点的Tag列表 /// /// Label节点的名称 /// 被勾选Checkbox节点的Tag列表 public List GetCheckboxTagsUnderLabelNode(string labelNodeName) { var tags = new List(); List 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(IEnumerable? 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(node.Children, key); } return null; // throw new NotImplementedException($"方法:{System.Reflection.MethodBase.GetCurrentMethod()?.Name}的targetNode为空"); } public xControl? Find(IEnumerable? nodes, string key) where xTreeNode : class where xControl : DependencyObject { if (nodes == null) nodes = Nodes; xTreeNode targetNode = FindTreeNodes(nodes, key); if (targetNode == null) throw new NotImplementedException($"方法:{System.Reflection.MethodBase.GetCurrentMethod()?.Name}的targetNode为空"); return To(targetNode); } public xControl? To(xTreeNode node) where xTreeNode : class where xControl : DependencyObject { var treeViewItem = FindTreeViewItem(treeView, node); if (treeViewItem != null) { xControl xCtrl = FindVisualChild(treeViewItem); if (xCtrl != null) { return xCtrl; } } throw new NotImplementedException( $"方法:{System.Reflection.MethodBase.GetCurrentMethod()?.Name}的{treeViewItem}为空"); } private TreeViewItem FindTreeViewItem(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(item, xTreeNode); if (childItem != null) { return childItem; } } } return null; } private T FindVisualChild(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(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 GetAllNodes() { return GetAllNodes(Nodes); } private IEnumerable GetAllNodes(IEnumerable 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(); } public string Text { get; set; } public ObservableCollection Children { get; set; } } /// /// Label类型的树节点 /// public class LabelTreeNode : TreeNode { } /// /// Label类型的树节点 /// public class ComboboxTreeNode : TreeNode { public string SelectedItem { get; set; } public ObservableCollection ComboBoxItems { get; set; } = new ObservableCollection(); } /// /// Checkbox类型的树节点 /// 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 }