using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; 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; using static System.Net.Mime.MediaTypeNames; using static System.Runtime.InteropServices.JavaScript.JSType; namespace Ramitta { public partial class winTreeList : UserControl, INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } 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 label = new Label() { Content = text }; var node = new LabelTreeNode { Text = text, obj = label }; AddNode(node, parent); return node; } public CheckboxTreeNode AddCheckboxNode(string text, string? tag = null, bool isChecked = false, TreeNode? parent = null) { var checkbox = new CheckBox() { IsChecked = isChecked, Content = text, Tag = tag ?? text, ToolTip = tag ?? text, VerticalAlignment = VerticalAlignment.Center }; // 处理选中状态变化 checkbox.Checked += (s, e) => OnCheckboxStateChanged(checkbox, true); checkbox.Unchecked += (s, e) => OnCheckboxStateChanged(checkbox, false); var node = new CheckboxTreeNode { Text = text, obj = checkbox }; AddNode(node, parent); return node; } public ComboboxTreeNode AddComboboxNode(string text, List? items = null, TreeNode? parent = null) { var combobox = new ComboBox() { SelectedIndex = 0, VerticalAlignment = VerticalAlignment.Center, MinWidth = 100 }; // 处理选择改变事件 combobox.SelectionChanged += (s, e) => { if (combobox.SelectedItem is string selected) { OnComboboxSelectionChanged(combobox, selected); } }; var node = new ComboboxTreeNode { Text = text, obj = combobox }; AddNode(node, parent); return node; } // 可选:添加事件处理方法 private void OnCheckboxStateChanged(CheckBox checkbox, bool isChecked) { // 这里可以处理复选框状态变化逻辑 Debug.WriteLine($"Checkbox '{checkbox.Tag}' changed to: {isChecked}"); } private void OnComboboxSelectionChanged(ComboBox combobox, string selectedValue) { // 这里可以处理组合框选择变化逻辑 Debug.WriteLine($"Combobox selection changed to: {selectedValue}"); } #endregion #region 查(这里面的函数下一个版本全被杀) /// /// 获取所有被勾选的Checkbox节点的Tag /// /// 当前节点集合 /// 被勾选Checkbox节点的Tag列表 public List GetCheckedCheckboxTags(IEnumerable nodes) { var tags = new List(); foreach (var node in nodes) { if (node is CheckboxTreeNode checkboxNode && (checkboxNode.obj.IsChecked ?? false)) { tags.Add(checkboxNode.obj.Tag.ToString()); } // 递归查找子节点 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.obj.IsChecked != true) { tags.Add(checkboxNode.obj.Tag.ToString()); } // 递归查找子节点 tags.AddRange(GetCheckedCheckboxTags(node.Children)); } return tags; } #endregion #region 查 /// /// 按照指定key路径查找元素(返回一个) /// public TreeNode? FindArgvNode(IEnumerable nodes, List key) { if (nodes == null) nodes = Nodes; 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 = FindArgvNode(node.Children, key.Skip(1).ToList()); if (foundNode != null) { return foundNode; } } return null; } public List? FindTreeNodes(IEnumerable? nodes, string key) where xTreeNode : class { List? result = null; if (nodes == null) nodes = Nodes; foreach (var node in nodes) { // 检查当前节点是否匹配 if (node.Text == key && node is xTreeNode) { if(result == null) result = new List(); result.Add(node as xTreeNode); } // 跳过空子 if (node.Children.Count == 0) continue; // 迭代下层 List? res = FindTreeNodes(node.Children, key); if (res == null)continue; if (res.Count != 0) { if (result == null) result = new List(); result.AddRange(res); } } return result; } // 改这个玩意 public xControl? Find(IEnumerable? nodes, string key) where xTreeNode : class where xControl : DependencyObject { if (nodes == null) nodes = Nodes; xTreeNode? targetNode = FindTreeNodes(nodes, key)[0]; if (targetNode == null) return null; else 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; } } return null; } 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; } public JObject JsonPrint(IEnumerable? nodes, int loop = 0) { // 如果传入的节点为空,使用默认的 Nodes 集合 if (nodes == null) nodes = Nodes; JObject resultObject = new JObject(); // 为每个节点构建一个 JObject foreach (var node in nodes) { JObject nodeObject = new JObject(); // 为当前节点添加基本信息 nodeObject["Type"] = node.GetType().Name; if (node.GetType() == typeof(CheckboxTreeNode)) { nodeObject["IsChecked"] = (node as CheckboxTreeNode)?.obj.IsChecked.ToString(); } if (node.GetType() == typeof(ComboboxTreeNode)) { var target = node as ComboboxTreeNode; nodeObject["SelectedItem"] = target?.obj.SelectedItem.ToString(); } // 处理子节点 if (node.Children.Count > 0) { // 递归调用以处理子节点,并将结果放在 "child" 属性下 JObject childrenObject = JsonPrint(node.Children, loop + 1); nodeObject["child"] = childrenObject; } // 使用节点文本作为属性名,将当前节点对象添加到结果中 resultObject.Add(node.Text, nodeObject); } // 返回结果对象 return resultObject; } #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 : INotifyPropertyChanged { private string _text; private ObservableCollection _children; public event PropertyChangedEventHandler? PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public TreeNode() { _children = new ObservableCollection(); } public string Text { get => _text; set { if (_text != value) { _text = value; OnPropertyChanged(nameof(Text)); } } } public ObservableCollection Children { get => _children; set { if (_children != value) { _children = value; OnPropertyChanged(nameof(Children)); } } } } /// /// Label类型的树节点 /// public class LabelTreeNode : TreeNode { private Label _obj; public Label obj { get => _obj; set { if (_obj != value) { _obj = value; OnPropertyChanged(nameof(obj)); } } } } /// /// Combobox类型的树节点 /// public class ComboboxTreeNode : TreeNode { private ComboBox _obj; public ComboBox obj { get => _obj; set { if (_obj != value) { _obj = value; OnPropertyChanged(nameof(obj)); } } } } /// /// Checkbox类型的树节点 /// public class CheckboxTreeNode : TreeNode { private CheckBox _obj; public CheckBox obj { get => _obj; set { if (_obj != value) { _obj = value; OnPropertyChanged(nameof(obj)); } } } } #endregion }