C#中实现一个TreeGridView(树形表格)附源码下载
生活随笔
收集整理的這篇文章主要介紹了
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#中提示:可访问性不一致:参数类型XX
- 下一篇: 系统架构设计师考试知识点整理-2:进程的