.NET C# 树遍历、查询、拷贝与可视化

.NET C# 树遍历、查询、拷贝与可视化

目录

  • .NET C# 树遍历、查询、拷贝与可视化
    • 1 组件安装
      • 1.1 NuGet包管理器安装:
      • 1.2 控制台安装:
    • 2 接口
      • 1.1 ITree\<TTreeNode\>
      • 1.2 ITree\<TKey, TTreeNode\>
      • 1.3 IObservableTree\<TTreeNode\>
      • 1.4 IObservableTree\<TKey, TTreeNode\>
    • 3 方法
      • Clone()
      • Search(Func\<TTreeNode, bool\> expression, bool isClone = false)
      • Traversal(Action\<TTreeNode\> expression)
      • SafeTraversal(Action\<TTreeNode\> expression)
      • Filter(Func\<TTreeNode, bool\> expression)
    • 4 样例源码

树结构组件,支持查询、遍历、拷贝、可视树过滤(不改变树结构,只过滤显示效果)

1 组件安装

1.1 NuGet包管理器安装:

image-20240625110819315

1.2 控制台安装:

NuGet\Install-Package Zhy.Components.Tree -Version 1.0.3
NuGet\Install-Package Zhy.Components.Tree.Extension -Version 1.0.3

2 接口

1.1 ITree<TTreeNode>

public class TestTree : ITree<TestTree>
{
    public string Id { get; set; }
    public string Name { get; set; }
    public TestTree Parent { get; set; }
    public List<TestTree> Children { get; set; }

    public TestTree(string id, string name, TestTree parent, List<TestTree> children)
    {
        Id = id;
        Name = name;
        Parent = parent;
        Children = children;
    }

    public TestTree Clone()
    {
        var childListClone = new List<TestTree>();
        if (Children != null)
        {
            foreach (var child in Children)
            {
                var childClone = child.Clone();
                childClone.Parent = this;
                childListClone.Add(childClone);
            }
        }
        return new TestTree(Id, Name, null, childListClone);
    }
}

1.2 ITree<TKey, TTreeNode>

public class TestTree2 : ITree<string, TestTree2>
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Key { get; set; }
    public string PKey { get => Parent?.Key; }
    public TestTree2 Parent { get; set; }
    public List<TestTree2> Children { get; set; }

    public TestTree2 this[string key]
    {
        get => Children.First(x => x.Key == key);
        set 
        {
            TestTree2 node = Children.First(x => x.Key == key);
            int idx = Children.IndexOf(node);
            Children[idx] = value;
        }
    }

    public TestTree2(string id, string name, string key, TestTree2 parent, List<TestTree2> children)
    {
        Id = id;
        Name = name;
        Key = key;
        Parent = parent;
        Children = children;
    }

    public TestTree2 Clone()
    {
        var childListClone = new List<TestTree2>();
        if (Children != null)
        {
            foreach (var child in Children)
            {
                var childClone = child.Clone();
                childClone.Parent = this;
                childListClone.Add(childClone);
            }
        }
        return new TestTree2(Id, Name, Key, null, childListClone);
    }
}

1.3 IObservableTree<TTreeNode>

public class TestTree : ITree<TestTree>
{
    public string Id { get; set; }
    public string Name { get; set; }
    public TestTree Parent { get; set; }
    public List<TestTree> Children { get; set; }

    public TestTree(string id, string name, TestTree parent, List<TestTree> children)
    {
        Id = id;
        Name = name;
        Parent = parent;
        Children = children;
    }

    public TestTree Clone()
    {
        var childListClone = new List<TestTree>();
        if (Children != null)
        {
            foreach (var child in Children)
            {
                var childClone = child.Clone();
                childClone.Parent = this;
                childListClone.Add(childClone);
            }
        }
        return new TestTree(Id, Name, null, childListClone);
    }
}

1.4 IObservableTree<TKey, TTreeNode>

public class TestTree2 : ITree<string, TestTree2>
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Key { get; set; }
    public string PKey { get => Parent?.Key; }
    public TestTree2 Parent { get; set; }
    public List<TestTree2> Children { get; set; }

    public TestTree2 this[string key]
    {
        get => Children.First(x => x.Key == key);
        set
        {
            TestTree2 node = Children.First(x => x.Key == key);
            int idx = Children.IndexOf(node);
            Children[idx] = value;
        }
    }

    public TestTree2(string id, string name, string key, TestTree2 parent, List<TestTree2> children)
    {
        Id = id;
        Name = name;
        Key = key;
        Parent = parent;
        Children = children;
    }

    public TestTree2 Clone()
    {
        var childListClone = new List<TestTree2>();
        if (Children != null)
        {
            foreach (var child in Children)
            {
                var childClone = child.Clone();
                childClone.Parent = this;
                childListClone.Add(childClone);
            }
        }
        return new TestTree2(Id, Name, Key, null, childListClone);
    }
}

3 方法

Clone()

深拷贝方法,继承接口时实现。

TestTree testTree = new TestTree("0", "root", null, new List<TestTree>());
TestTree testTreeClone = testTree.Clone();

Search(Func<TTreeNode, bool> expression, bool isClone = false)

树查询方法。

expression: 委托,参数为树节点,返回值为True/False,表示节点是否符合查询规则;

isClone: 是否克隆新的对象,True - 在新的树上进行查询及修改,并返回新的树,False - 在原始树上进行查询及修改;

TestTree searchResult = testTree.Search(node => node.Name.StartsWith("vect"), true);

Traversal(Action<TTreeNode> expression)

树遍历方法。

expression: 委托,参数为树节点,遍历所有节点执行;

testTree.Traversal(node => Console.WriteLine(node.Name));

SafeTraversal(Action<TTreeNode> expression)

安全的树遍历,若遍历时对树节点结构进行修改时使用。

testTree.SafeTraversal(node =>
{
    if (node.Name.EndsWith("1"))
    {
        node.Parent.Children.Remove(node);
    }
});

Filter(Func<TTreeNode, bool> expression)

可视树过滤,不改变树结构,只影响树结构的可视化显示。

expression: 委托,参数为树节点,返回值为True/False,表示节点是否符合过滤规则;

testTree.Filter(n => n.Name.Contains(SearchText));

Zhy.Components.ObservableTree.Filter

4 样例源码

TestTreeNode.cs

using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;

namespace Zhy.Components.Tree.Test
{
    public partial class TestTreeNode : ObservableObject, IObservableTree<TestTreeNode>
    {
        public TestTreeNode Parent { get; set; }

        [ObservableProperty]
        private string _name;

        [ObservableProperty]
        private ObservableCollection<TestTreeNode> _children;
        //public ObservableCollection<TestTreeNode> Children 
        //{
        //    get => _children;
        //    set => SetProperty(ref _children, value);
        //}

        public TestTreeNode Clone()
        {
            TestTreeNode clone = new TestTreeNode
            {
                Name = _name,
            };
            if (Children?.Count > 0)
            {
                clone.Children = new ObservableCollection<TestTreeNode>();
                foreach (var child in Children)
                {
                    TestTreeNode subClone = child.Clone();
                    subClone.Parent = this;
                    clone.Children.Add(subClone);
                }
            }
            return clone;
        }
    }
}

MainWindow.xaml

<Grid Margin="10">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <DockPanel>
        <Button
            Command="{Binding SearchCommand}"
            Content="查  询"
            Cursor="Hand"
            DockPanel.Dock="Right" />
        <TextBox Text="{Binding SearchText}" />
    </DockPanel>
    <TreeView
        Grid.Row="1"
        HorizontalContentAlignment="Stretch"
        VerticalContentAlignment="Stretch"
        ItemsSource="{Binding TreeNodes}">
        <TreeView.ItemContainerStyle>
            <Style TargetType="TreeViewItem">
                <Setter Property="IsExpanded" Value="True" />
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                <DockPanel x:Name="dp" Margin="0,2,0,2">
                    <TextBlock
                        VerticalAlignment="Center"
                        FontSize="14"
                        IsHitTestVisible="True"
                        Text="{Binding Name}" />
                    <TextBlock IsHitTestVisible="True" />
                </DockPanel>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</Grid>

MainWindowViewModel.cs

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
using Zhy.Components.Tree.Extension;

namespace Zhy.Components.Tree.Test
{
    public partial class MainWindowViewModel : ObservableObject
    {
        [ObservableProperty]
        private ObservableCollection<TestTreeNode> _treeNodes;
        [ObservableProperty]
        private string _searchText;

        public MainWindowViewModel()
        {
            _treeNodes = new ObservableCollection<TestTreeNode>
            {
                new TestTreeNode
                {
                    Name = "资源目录",
                    Children = new ObservableCollection<TestTreeNode>
                    {
                        new TestTreeNode
                        {
                            Name = "矢量",
                            Children = new ObservableCollection<TestTreeNode>
                            {
                                new TestTreeNode
                                {
                                    Name = "行政区划",
                                    Children = new ObservableCollection<TestTreeNode>
                                    {
                                        new TestTreeNode
                                        {
                                            Name = "北京行政区划"
                                        },
                                        new TestTreeNode
                                        {
                                            Name = "天津行政区划"
                                        },
                                        new TestTreeNode
                                        {
                                            Name = "河北行政区划"
                                        },
                                    }
                                },
                                new TestTreeNode
                                {
                                    Name = "管线",
                                }
                            }
                        },
                        new TestTreeNode
                        {
                            Name = "栅格",
                            Children = new ObservableCollection<TestTreeNode>
                            {
                                new TestTreeNode
                                {
                                    Name = "正射影像",
                                    Children = new ObservableCollection<TestTreeNode>
                                    {
                                        new TestTreeNode
                                        {
                                            Name = "北京遥感影像"
                                        },
                                        new TestTreeNode
                                        {
                                            Name = "天津遥感影像"
                                        },
                                        new TestTreeNode
                                        {
                                            Name = "河北遥感影像"
                                        },
                                    }
                                },
                                new TestTreeNode
                                {
                                    Name = "DEM"
                                }
                            }
                        }
                    }
                },
            };
        }

        [RelayCommand]
        private void Search()
        {
            foreach (var item in TreeNodes)
            {
                item.Filter(n => n.Name.Contains(SearchText));
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/745495.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

推荐一本RMS包作者写的我正在追读的书《Regression Modeling Strategies》

熟悉我的粉丝都清楚&#xff0c;我很少推荐书&#xff0c;这次推荐这本书是我目前正在读的&#xff0c;这是本老书了&#xff0c;关于回归模型的&#xff0c;我觉得写的很好。 写这本书的就是RMS包的作者&#xff0c;这是他早些年写的书&#xff0c;我们可以结合他写的书来加深…

2006年上半年软件设计师【上午题】试题及答案

文章目录 2006年上半年软件设计师上午题--试题2006年上半年软件设计师上午题--答案 2006年上半年软件设计师上午题–试题 2006年上半年软件设计师上午题–答案

java启动命令与参数配置

1. java启动命令 运行一个java应用程序的语法分两种&#xff0c;分别为&#xff1a; 执行类&#xff1a;java [-options] class [args…] 执行jar文件&#xff1a;java [-options] -jar jarfile [args…] 其中 [-options] 配置 JVM参数&#xff0c;[args…] 配置 Java 运行参…

牛客链表刷题(四)

目录 一、链表的奇偶重排 代码&#xff1a; 二、删除有序链表中重复的元素-I 代码&#xff1a; 三、删除有序链表中重复的元素-II 代码&#xff1a; 一、链表的奇偶重排 代码&#xff1a; import java.util.*;/** public class ListNode {* int val;* ListNode next nu…

VisualStudio2019受支持的.NET Core

1.VS Studio2019受支持的.NET Core&#xff1f; 适用于 Visual Studio 的 .NET SDK 下载 (microsoft.com) Visual Studio 2019 默认并不直接支持 .NET 6 及以上版本。要使用 .NET 6 或更高版本&#xff0c;你需要在 Visual Studio 2019 中采取额外步骤&#xff0c;比如安装相应…

钢琴灯护眼灯怎么选比较好?五款爆款护眼大路灯推荐

钢琴灯护眼灯怎么选比较好&#xff1f;想要避免孩子在学习时眼睛视力不受影响&#xff0c;除了纠正写作姿势、带出去晒太阳、多看绿色植物舒缓眼睛疲劳之外&#xff0c;剩下的就是光环境问题&#xff0c;毕竟现在的小朋友学业越来越重&#xff0c;大部分时间不是在学校学习就是…

6.20模板

c/c/jave 静态语言强类型语言编译型语言&#xff0c;想要在运行以前就能够找出错误。 python是一个弱类型语言&#xff0c;在运行的时候再确定变量的类型。 背景需求&#xff1a;想要在强类型严格的要求下希望能够更加灵活。 有三种方式可以实现&#xff1a;宏定义&#xff…

各场景ChatGPT指令Promp提示词大全

一、Promp指令使用指南 直接复制Promp指令提示词使用 可以前往已经添加好Prompt预设的AI系统测试使用&#xff08;可自定义添加使用&#xff09; 支持GPTs应用Prompt自定义预设应用 SparkAi SparkAi创作系统是一款基于ChatGPT和Midjourney开发的智能问答和绘画系统&#xff…

Vue2中为啥不用 Object.defineProperty 实现响应式数组 ? 不能监听到数组变化吗?

Vue2.0 对于数据响应式的实现上是有一些局限性的&#xff0c;比如&#xff1a; 无法检测数组和对象的新增&#xff1b; 无法检测通过索引改变数组的操作&#xff1b; 针对以上问题&#xff0c;我们一般都会把锅甩给 Object.defineProperty。所以&#xff0c;在Vue 3.0 中&am…

uniapp 小程序 堆叠轮播图 左滑 右滑 自动翻页 点击停止自动翻页

uniapp 小程序 堆叠轮播图 左滑 右滑 自动翻页 点击停止自动翻页 超过指定时间未点击滑动 则继续开始滚动 直接上代码 componentSwiper.vue 需要注意页面切换时清除计时器 <template><view><view class"swiperPanel" touchstart"startMove"…

STM32烧写hex及bin文件的五种方法

一.STVP 1.概述 STVP是ST早期的一款下载编程工具&#xff0c;支持早期的ST早期的芯片&#xff08;比如ST7系列&#xff09;&#xff0c;也支持STM8、 STM32。 该工具虽然相对ST-LINK utility、STM32CubeProg比较老&#xff0c;但该工具官方在2017年还进行了维护&#xff0c;现…

基于web的摩托车销售系统的设计与实现-计算机毕业设计源码031706

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对摩托车销售系统等问题&#xff0c;对摩托车…

<sa8650>QCX Usecase 使用详解— Spectra Studio工程建立

<sa8650>QCX Usecase 使用详解— Spectra Studio工程建立 一 前言二 建立usecase工程2.1 前提2.2 创建usecase工程3.2 查看usecase2三 总结一 前言 目前高通平台在camera模块中,我们会使用到usecase这么一个功能模块;本文主要讲解sa8650平台中,通过Spectra Studio 可视化…

[C/C++][VsCode]使用VsCode在Linux上开发和Vscode在线调试

目录 0. 前言1. win10上搭建环境Linux环境2.编写makefile3.怎么在线调试结语 0. 前言 在开发中&#xff0c;可以一边开发一边调试&#xff0c;这样可以大大的减少bug&#xff1b;但是正常来说一个大点的项目&#xff0c;是不太可能单步调试的&#xff0c;因为一般都是用make或…

无人机螺旋桨理论教学培训课程

本文档为一份详细的关于TYTO机器人公司提供的电机和螺旋桨理论及其实验操作的指南。指南首先概述了材料、实验目标以及实验的介绍部分&#xff0c;随后详细阐述了理论问题、实验步骤和附录内容。实验目的在于通过实际测试来测量和理解不同螺旋桨参数对无人机性能的影响&#xf…

手把手教你使用kimi创建流程图【实践篇】

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 引言 在昨日的文章中&#xff0c;我们介绍了如何使用Kimi生成论文中的流程图。今天&#xff0c;我们将更进一步&#xff0c;通过实践案例来展示Kimi在生成流程图方面的应用。这不仅将加…

回归洛伦兹变换

现在再回到洛伦兹变换&#xff0c; 将其写成上角标表示惯性系的形式&#xff08;注意不是幂次&#xff09;&#xff0c; 并且认为洛伦兹变换中的两个方程的比例常数&#xff0c; 并不仅仅是因为虚数单位数量巨大导致的“误判”&#xff0c;虽然这也是说得通的。因为我们已经看到…

Python 爬虫从入门到入狱之路一

实际上爬虫一共就四个主要步骤&#xff1a; 明确目标 (要知道你准备在哪个范围或者网站去搜索)爬 (将所有的网站的内容全部爬下来)取 (去掉对我们没用处的数据)处理数据&#xff08;按照我们想要的方式存储和使用&#xff09; 我们在之前写的爬虫程序中&#xff0c;都只是获取…

通讯:单片机串口和电脑通讯

目录 1.串口输出数据到电脑 硬件部分 串口输出数据到电脑的软件软件部分&#xff1a; 相关问题&#xff1a; 2.单片机串口--485--485转USB--电脑 串口&#xff0c;芯片&#xff0c;转换器&#xff0c;设备之间的通讯的接线&#xff0c;都是要TX--RX, RX--TX 交叉连接。 单…

基于springboot+Vue高校宿舍管理系统的设计与实现【附源码】

本科毕业设计&#xff08;论文&#xff09; 基于springbootVue高校宿舍管理系统的设计与实现 目录 摘要 2 第一章 绪论 2 1.1 开发背景 2 1.2 开发意义 2 第二章 系统分析 3 2.1 系统的需求分析 3 2.2 系统开发设计思想 3 2.3系统开发步骤 3 2.4 系统的主要技术 4 2.4.1 B/S系…