C#中实现一个TreeGridView(树形表格)附源码下载
场景
效果
示例源码下载
https://download.csdn.net/download/badao_liumang_qizhi/11593399
实现
新建一个Winform程序,然后在页面上拖拽一个DataGridView和一个Button。
布局如下:
其中DataGridView点击右上角新增列,然后添加两列。
右击项目-添加--类
其中后三个字段属性是必须的,Level代表节点层次,ChildList代表子节点。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace TreeGridViewTestOnly
{public class Person{public int id;public int Id{get { return id; }set { id = value; }}public string password;public string Password{get { return password; }set { password = value; }}private int level;public int Level{get { return level; }set { level = value; }}private bool isExpanded;public bool IsExpanded{get { return isExpanded; }set { isExpanded = value; }}private List<Person> childList;public List<Person> ChildList{get { return childList; }set { childList = value; }}}
}
双击窗体进入窗体的加载事件中
private void Form1_Load(object sender, EventArgs e){//首先生成数据this.GenerateData();//然后生成列this.GenerateClo();}
在生成数据的方法中
/// <summary>/// 生成数据/// </summary>private void GenerateData() {for (int i = 0; i < 100; i++){Person p1 = new Person() { Id = i, Password = "密码" + i, Level = 1 };for (int j = 0; j < 10; j++){Person p2 = new Person() { Id = j, Password = "密码" + j, Level = 2 };for (int k = 0; k < 10; k++){Person p3 = new Person() { Id = k, Password = "密码" + k, Level = 3 };if (p2.ChildList == null){p2.ChildList = new List<Person>();}p2.ChildList.Add(p3);}if (p1.ChildList == null){p1.ChildList = new List<Person>();}p1.ChildList.Add(p2);}personList.Add(p1);}}
如果是三层树结构就这样三层循环,几层机构依次类推。
在生成列的方法中
private void GenerateClo(){this.dataGridView1.ReadOnly = true;this.dataGridView1.AllowUserToAddRows = false;this.dataGridView1.AllowUserToDeleteRows = false;this.dataGridView1.AllowUserToOrderColumns = false;this.dataGridView1.AllowUserToResizeRows = false;this.dataGridView1.AllowUserToResizeColumns = false;#region 影响性能this.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;this.dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;this.dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;this.dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;#endregionthis.dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None;//this.dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;this.dataGridView1.RowHeadersVisible = false;this.dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;this.dataGridView1.VirtualMode = true;this.dataGridView1.CellValueNeeded -= dataGridView1_CellValueNeeded;this.dataGridView1.CellValueNeeded += dataGridView1_CellValueNeeded;this.dataGridView1.Columns.Clear();int colWidth = 100;DataGridViewImageColumn colImg = new DataGridViewImageColumn();colImg.HeaderText = String.Empty;colImg.Width = 20;DataGridViewTextBoxColumn colId = new DataGridViewTextBoxColumn();colId.Name = "colId";colId.HeaderText = "序号";colId.MinimumWidth = 160;DataGridViewTextBoxColumn colA = new DataGridViewTextBoxColumn();colA.HeaderText = "ID";colA.Width = colWidth;DataGridViewTextBoxColumn colB = new DataGridViewTextBoxColumn();colB.HeaderText = "密码";colB.Width = colWidth;this.dataGridView1.Columns.Add(colId);this.dataGridView1.Columns.Add(colA);this.dataGridView1.Columns.Add(colB);foreach (DataGridViewColumn col in this.dataGridView1.Columns){col.ReadOnly = true;}this.dataGridView1.CellMouseClick += dataGridView1_CellMouseClick;}
其中生成列所用到的方法
private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e){if (e.RowIndex >= this.dataGridView1.RowCount || e.RowIndex > this.personList.Count){return;}Random r = new Random();r.NextDouble();Person record = this.personList[e.RowIndex];object[] values = new object[] { record.Id, record.id, record.password };e.Value = values[e.ColumnIndex];if (e.ColumnIndex == 0){Person currRecord = this.personList[e.RowIndex];if (currRecord.ChildList != null && currRecord.ChildList.Count > 0){if (currRecord.IsExpanded){e.Value = GenerateSpace(currRecord.Level) + " [-] " + values[e.ColumnIndex];}else{e.Value = GenerateSpace(currRecord.Level) + " [+] " + values[e.ColumnIndex];}}else{e.Value = GenerateSpace(currRecord.Level + 1) + values[e.ColumnIndex];}}}/// <summary>/// 根据节点级别生成要显示的空格数/// </summary>/// <param name="level"></param>/// <returns></returns>public string GenerateSpace(int level){int step = 5;StringBuilder sb = new StringBuilder();for (int i = 0; i < step * (level - 1); i++){sb.Append(" ");}return sb.ToString();}void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e){if (dataGridView1.Columns[e.ColumnIndex].Name == "colId"){Console.WriteLine("MouseClick...");if (this.personList[e.RowIndex].ChildList != null && this.personList[e.RowIndex].ChildList.Count > 0){if (this.personList[e.RowIndex].IsExpanded){//this.lst2.RemoveRange(e.RowIndex + 1, this.lst2[e.RowIndex].ChildList.Count);this.RecursiveRemove(this.personList, e.RowIndex);this.personList[e.RowIndex].IsExpanded = false;this.ShowData(this.personList);}else{this.personList.InsertRange(e.RowIndex + 1, this.personList[e.RowIndex].ChildList);this.personList[e.RowIndex].IsExpanded = true;this.ShowData(this.personList);}this.dataGridView1.Rows[0].Selected = false;this.dataGridView1.Rows[e.RowIndex].Selected = true;}}}/// <summary>/// 递归移除/// </summary>/// <param name="lst"></param>/// <param name="index"></param>/// <param name="count"></param>public void RecursiveRemove(List<Person> lst, int index){int count = GetAllExpandChildCount(lst[index]);lst.RemoveRange(index + 1, count);}public int GetAllExpandChildCount(Person r){if (r.ChildList != null && r.ChildList.Count > 0){int cnt = 0;if (r.IsExpanded){cnt = r.ChildList.Count;for (int i = 0; i < r.ChildList.Count; i++){cnt += GetAllExpandChildCount(r.ChildList[i]);}}r.IsExpanded = false;return cnt;}else{return 0;}}
然后声明一个全局变量存放数据
public partial class Form1 : Form{public List<Person> personList = new List<Person>();
在Button的点击事件中
private void button1_Click(object sender, EventArgs e){this.ShowData(this.personList);}public void ShowData(List<Person> lst){int recordCount = lst.Count;this.dataGridView1.Rows.Clear();this.dataGridView1.RowCount = recordCount;}
完整示例代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace TreeGridViewTestOnly
{public partial class Form1 : Form{public List<Person> personList = new List<Person>();public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){//首先生成数据this.GenerateData();//然后生成列this.GenerateClo();}/// <summary>/// 生成数据/// </summary>private void GenerateData() {for (int i = 0; i < 100; i++){Person p1 = new Person() { Id = i, Password = "密码" + i, Level = 1 };for (int j = 0; j < 10; j++){Person p2 = new Person() { Id = j, Password = "密码" + j, Level = 2 };for (int k = 0; k < 10; k++){Person p3 = new Person() { Id = k, Password = "密码" + k, Level = 3 };if (p2.ChildList == null){p2.ChildList = new List<Person>();}p2.ChildList.Add(p3);}if (p1.ChildList == null){p1.ChildList = new List<Person>();}p1.ChildList.Add(p2);}personList.Add(p1);}}/// <summary>/// 生成列/// </summary>private void GenerateClo(){this.dataGridView1.ReadOnly = true;this.dataGridView1.AllowUserToAddRows = false;this.dataGridView1.AllowUserToDeleteRows = false;this.dataGridView1.AllowUserToOrderColumns = false;this.dataGridView1.AllowUserToResizeRows = false;this.dataGridView1.AllowUserToResizeColumns = false;#region 影响性能this.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;this.dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;this.dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;this.dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;#endregionthis.dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None;//this.dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;this.dataGridView1.RowHeadersVisible = false;this.dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;this.dataGridView1.VirtualMode = true;this.dataGridView1.CellValueNeeded -= dataGridView1_CellValueNeeded;this.dataGridView1.CellValueNeeded += dataGridView1_CellValueNeeded;this.dataGridView1.Columns.Clear();int colWidth = 100;DataGridViewImageColumn colImg = new DataGridViewImageColumn();colImg.HeaderText = String.Empty;colImg.Width = 20;DataGridViewTextBoxColumn colId = new DataGridViewTextBoxColumn();colId.Name = "colId";colId.HeaderText = "序号";colId.MinimumWidth = 160;DataGridViewTextBoxColumn colA = new DataGridViewTextBoxColumn();colA.HeaderText = "ID";colA.Width = colWidth;DataGridViewTextBoxColumn colB = new DataGridViewTextBoxColumn();colB.HeaderText = "密码";colB.Width = colWidth;this.dataGridView1.Columns.Add(colId);this.dataGridView1.Columns.Add(colA);this.dataGridView1.Columns.Add(colB);foreach (DataGridViewColumn col in this.dataGridView1.Columns){col.ReadOnly = true;}this.dataGridView1.CellMouseClick += dataGridView1_CellMouseClick;}private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e){if (e.RowIndex >= this.dataGridView1.RowCount || e.RowIndex > this.personList.Count){return;}Random r = new Random();r.NextDouble();Person record = this.personList[e.RowIndex];object[] values = new object[] { record.Id, record.id, record.password };e.Value = values[e.ColumnIndex];if (e.ColumnIndex == 0){Person currRecord = this.personList[e.RowIndex];if (currRecord.ChildList != null && currRecord.ChildList.Count > 0){if (currRecord.IsExpanded){e.Value = GenerateSpace(currRecord.Level) + " [-] " + values[e.ColumnIndex];}else{e.Value = GenerateSpace(currRecord.Level) + " [+] " + values[e.ColumnIndex];}}else{e.Value = GenerateSpace(currRecord.Level + 1) + values[e.ColumnIndex];}}}/// <summary>/// 根据节点级别生成要显示的空格数/// </summary>/// <param name="level"></param>/// <returns></returns>public string GenerateSpace(int level){int step = 5;StringBuilder sb = new StringBuilder();for (int i = 0; i < step * (level - 1); i++){sb.Append(" ");}return sb.ToString();}void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e){if (dataGridView1.Columns[e.ColumnIndex].Name == "colId"){Console.WriteLine("MouseClick...");if (this.personList[e.RowIndex].ChildList != null && this.personList[e.RowIndex].ChildList.Count > 0){if (this.personList[e.RowIndex].IsExpanded){//this.lst2.RemoveRange(e.RowIndex + 1, this.lst2[e.RowIndex].ChildList.Count);this.RecursiveRemove(this.personList, e.RowIndex);this.personList[e.RowIndex].IsExpanded = false;this.ShowData(this.personList);}else{this.personList.InsertRange(e.RowIndex + 1, this.personList[e.RowIndex].ChildList);this.personList[e.RowIndex].IsExpanded = true;this.ShowData(this.personList);}this.dataGridView1.Rows[0].Selected = false;this.dataGridView1.Rows[e.RowIndex].Selected = true;}}}/// <summary>/// 递归移除/// </summary>/// <param name="lst"></param>/// <param name="index"></param>/// <param name="count"></param>public void RecursiveRemove(List<Person> lst, int index){int count = GetAllExpandChildCount(lst[index]);lst.RemoveRange(index + 1, count);}public int GetAllExpandChildCount(Person r){if (r.ChildList != null && r.ChildList.Count > 0){int cnt = 0;if (r.IsExpanded){cnt = r.ChildList.Count;for (int i = 0; i < r.ChildList.Count; i++){cnt += GetAllExpandChildCount(r.ChildList[i]);}}r.IsExpanded = false;return cnt;}else{return 0;}}private void button1_Click(object sender, EventArgs e){this.ShowData(this.personList);}public void ShowData(List<Person> lst){int recordCount = lst.Count;this.dataGridView1.Rows.Clear();this.dataGridView1.RowCount = recordCount;}}
}
C#中实现一个TreeGridView(树形表格)附源码下载相关推荐
- C#中实现视频播放器窗体程序(附源码下载)
场景 效果 实现 新建窗体程序,然后从工具箱中拖拽DataGridView控件,然后在控件右上角点击新增列,设置好每列 的Name属性和Headertext属性. 新建Video类 项目-右击-新增- ...
- php实现电子签名,php实现往pdf中加数字签名操作示例【附源码下载】
本文实例讲述了php实现往pdf中加数字签名操作.分享给大家供大家参考,具体如下: //======================================================== ...
- Winforn中DevExpress的TreeList中显示某路径下的所有目录和文件(附源码下载)
场景 Winform中DevExpress的TreeList的入门使用教程(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...
- Web 开发中很实用的10个效果【附源码下载】
在工作中,我们可能会用到各种交互效果.而这些效果在平常翻看文章的时候碰到很多,但是一时半会又想不起来在哪,所以养成知识整理的习惯是很有必要的.这篇文章给大家推荐10个在 Web 开发中很有用的效果,记 ...
- Redis在Java中的使用及连接数据库(附源码)
Redis在Java中的使用及连接数据库(附源码) 引言: 本文主要分享了Redis如何在IDEA中部署,运行:模拟加入Redis的操作: 文章目录 Redis在Java中的使用及连接数据库(附源码) ...
- 美!视差滚动在图片滑块中的应用【附源码下载】
视差滚动(Parallax Scrolling)已经被广泛应用于网页设计中,这种技术能够让原本平面的网页界面产生动感的立体效果.下面分享的这个图片滑块效果是难得一见的结合视差滚动的例子,之前的文章给大 ...
- 美!视差滚动特效在图片滑块中的应用【附源码下载】
视差滚动(Parallax Scrolling)已经被广泛应用于网页设计中,这种技术能够让原本平面的网页界面产生动感的立体效果.下面分享的这个图片滑块效果是难得一见的结合视差滚动的例子,之前的文章给大 ...
- 我搭建了一个随机「毒鸡汤」语录网站附源码下载
小伙伴们注意:公众号的推送机制不再按照时间前后推送了,微信公众号信息流乱序.君哥建议大家把科技毒瘤君公众号置顶(设为星标⭐),以便第一时间看到推送,非常感谢~,方法如下图: 1 演示效果 ★ 遇到喜欢 ...
- vscode中安装webpack_leaflet-webpack 入门开发系列一初探篇(附源码下载)
前言 leaflet-webpack 入门开发系列环境知识点了解: node 安装包下载 webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载地址w ...
最新文章
- 《机器人与数字人:基于MATLAB的建模与控制》——2.3节指数映射和k过程
- neoterm如何安装python_NeoTerm下载-NeoTerm(安卓终端)下载v2.1.0-be8d6cf 安卓版-西西软件下载...
- Python学习(四)列表与列表操作
- LINQ中的动态排序
- java创建一个程序把输入字符串的大小写互换_8 编写程序,从键盘接收一个字符串,对字符串中的字母进行大小写互转...
- SpringBoot启动流程分析(四):IoC容器的初始化过程
- 特定视图呈现时发生的事件顺序
- python 检测文件更新失败_依赖错误,检测更新失败,提示这个
- 解决桌面右键无NVIDIA控制面板选项
- fw325r虚拟服务器,fw325r无线路由器设置
- php attr属性,jquery 获取 自定义属性(attr 和 prop)
- YUI中一些方法总结
- 有向图的强连通分量(SCC)
- 2022年系统集成项目管理工程师考试知识点:项目成本管理
- 游戏辅助制作核心--植物大战僵尸逆向之召唤僵尸call(九)
- 学习ios(必看经典)牛人40天精通iOS开发的学习方法
- 操作系统:动态内存分区分配算法实现(C++)
- background-size cover和contain的区别
- 1.3RK3288积累之命令1
- srt文件解析 c语言,c语言标准库函数srt排序的介绍与使用.docx
热门文章
- WINCE下的MINGW交叉编译环境下内存崩溃地址的查找方法。
- if语句 power query_PowerQuery学习:认识M函数
- map 长度_Python实用教程系列——高阶函数Map、Filter、Reduce
- springaop事务逻辑原理_架构师:一篇文章掌握——Spring 事务管理
- 拉格朗日c语言实验报告,拉格朗日插值法C语言的实现(实验报告)(9页)-原创力文档...
- android怎么长按一张图片保存到相册_instagram怎么保存图片?
- post 返回代码_减少冗长代码,利用DDT轻松分离测试数据
- html绘制头像原样教程,CSS实例教程:创意CSS3头像展示教程
- c语言周传生教材答案,C语言程序设计与实践(普通高等教育“十二五”规划教材)...
- java socket 如何设置so_keepalive属性_socket通信的KeepAlive设定