TreeView实现无限级分类示例

今天比较闲,用C#写了一个无限级分类的例子:
数据库如下:

use master

create database CategoryTest
use CategoryTest
create table Categories(
 [Id] int identity primary key not null,
 ParentId nvarchar(15) not null,
 CategoryName nvarchar(25),
 
)

insert Categories(ParentId,CategoryName)values(0,'总公司')

insert Categories(ParentId,CategoryName)values(1,'广州公司')
insert Categories(ParentId,CategoryName)values(1,'上海公司')
insert Categories(ParentId,CategoryName)values(1,'汕头公司')
insert Categories(ParentId,CategoryName)values(1,'深圳公司')

insert Categories(ParentId,CategoryName)values(2,'广州销售部')
insert Categories(ParentId,CategoryName)values(2,'广州服务部')
insert Categories(ParentId,CategoryName)values(2,'广州技术部')
insert Categories(ParentId,CategoryName)values(2,'广州行政部')

insert Categories(ParentId,CategoryName)values(8,'广州软件技术部')
insert Categories(ParentId,CategoryName)values(8,'广州硬件技术部')

select * from  Categories


一,用递归实现

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace UnlimitCategoryByRecusion
{
 /// <summary>
 /// 递归实现无限级分类。
 /// </summary>
 public class Form1 : System.Windows.Forms.Form
 {
  private System.Windows.Forms.TreeView tvCategory;
  /// <summary>
  /// 必需的设计器变量。
  /// </summary>
  private System.ComponentModel.Container components = null;

  public Form1()
  {
   InitializeComponent();
  }

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if(components != null)
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Windows 窗体设计器生成的代码
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>
  private void InitializeComponent()
  {
   this.tvCategory = new System.Windows.Forms.TreeView();
   this.SuspendLayout();
   //
   // tvCategory
   //
   this.tvCategory.ImageIndex = -1;
   this.tvCategory.Location = new System.Drawing.Point(8, 16);
   this.tvCategory.Name = "tvCategory";
   this.tvCategory.SelectedImageIndex = -1;
   this.tvCategory.Size = new System.Drawing.Size(272, 360);
   this.tvCategory.TabIndex = 0;
   //
   // Form1
   //
   this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
   this.ClientSize = new System.Drawing.Size(292, 398);
   this.Controls.Add(this.tvCategory);
   this.Name = "Form1";
   this.Text = "Form1";
   this.Load += new System.EventHandler(this.Form1_Load);
   this.ResumeLayout(false);

  }
  #endregion

  private void Form1_Load(object sender, System.EventArgs e) {
   if(!LoadData()){
    return;
   }
   AddRootNode();
  }
  
  private DataTable dt = new DataTable();
  private void AddRootNode(){
   TreeNode node = null;
   for(int i=0;i<dt.Rows.Count;i++){
    //寻找根节点
    if(dt.Rows[i]["ParentId"].ToString()=="0"){//0代表根节点
     node = new TreeNode();
     node.Tag=dt.Rows[i]["Id"].ToString();
     node.Text=dt.Rows[i]["CategoryName"].ToString();

     this.tvCategory.Nodes.Add(node);//加载根节点     
     AddChildNode(node);//加载支节点
    }
   }   
  }

  private void AddChildNode(TreeNode currentNode){
   TreeNode node = null;
   for(int i=0;i<dt.Rows.Count;i++){
    if(dt.Rows[i]["ParentId"].ToString()==currentNode.Tag.ToString()){
     node = new TreeNode();
     node.Tag=dt.Rows[i]["Id"].ToString();
     node.Text=dt.Rows[i]["CategoryName"].ToString();
     currentNode.Nodes.Add(node);
     AddChildNode(node);//递归加载所有节点     
    }
   }
  }

  /// <summary>
  /// 将数据库中分类表加载到DataSet中,避免遍历时经常操作数据库带来的性能下降
  /// </summary>
  /// <returns>加载成功后返回true</returns>
  private bool LoadData(){
   try{
    using(SqlConnection conn  =new SqlConnection("database=CategoryTest;uid=sa;pwd=sa")){
     conn.Open();
     string sql="select * from  Categories";
     using(SqlDataAdapter da = new SqlDataAdapter(sql,conn)){
      da.Fill(dt);
     }
    }
    return true;
   }catch(Exception ex){
    Console.WriteLine(ex.Message);
    Console.WriteLine(ex.StackTrace);
    //MessageBox.Show("读取数据出错");
    return false;
   }
  }
 }
}


 

二,非递归实现

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data;
namespace UnlimitCategory {
 /// <summary>
 /// 功能:树形控件实现无限级分类
 /// 作者:林振冲
 /// 时间:2008-6-25
 /// </summary>
 public class Form1 : System.Windows.Forms.Form {
  private System.Windows.Forms.TreeView tvCategory;
  /// <summary>
  /// 必需的设计器变量。
  /// </summary>
  private System.ComponentModel.Container components = null;

  public Form1() {
   //
   // Windows 窗体设计器支持所必需的
   //
   InitializeComponent();

   //
   // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
   //
  }

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  protected override void Dispose( bool disposing ) {
   if( disposing ) {
    if(components != null) {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Windows 窗体设计器生成的代码
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>
  private void InitializeComponent() {
   this.tvCategory = new System.Windows.Forms.TreeView();
   this.SuspendLayout();
   //
   // tvCategory
   //
   this.tvCategory.ImageIndex = -1;
   this.tvCategory.Location = new System.Drawing.Point(16, 16);
   this.tvCategory.Name = "tvCategory";
   this.tvCategory.SelectedImageIndex = -1;
   this.tvCategory.Size = new System.Drawing.Size(232, 312);
   this.tvCategory.TabIndex = 0;
   this.tvCategory.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.tvCategory_BeforeExpand);
   //
   // Form1
   //
   this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
   this.ClientSize = new System.Drawing.Size(292, 350);
   this.Controls.Add(this.tvCategory);
   this.Name = "Form1";
   this.Text = "Form1";
   this.Load += new System.EventHandler(this.Form1_Load);
   this.ResumeLayout(false);

  }
  #endregion
  private DataTable dt = new DataTable();
  private void Form1_Load(object sender, System.EventArgs e) {
   if(!LoadData()){
    return;
   }
   AddRootNode();
  }
  //加载根节点前两级节点
  private void AddRootNode(){
   TreeNode node = null;
   for(int i=0;i<dt.Rows.Count;i++){
    //寻找根节点
    if(dt.Rows[i]["ParentId"].ToString()=="0"){//0代表根节点
     node = new TreeNode();
     node.Tag=dt.Rows[i]["Id"].ToString();
     node.Text=dt.Rows[i]["CategoryName"].ToString();

     this.tvCategory.Nodes.Add(node);//加载根节点     
     AddChildNode(node);//加载支节点
    }
   }   
  }

  private void AddChildNode(TreeNode currentNode){
   TreeNode node = null;
   for(int i=0;i<dt.Rows.Count;i++){
    if(dt.Rows[i]["ParentId"].ToString()==currentNode.Tag.ToString()){
     node = new TreeNode();
     node.Tag=dt.Rows[i]["Id"].ToString();
     node.Text=dt.Rows[i]["CategoryName"].ToString();
     currentNode.Nodes.Add(node);
    }    
   }
  }
  /// <summary>
  /// 将数据库中分类表加载到DataSet中,避免遍历时经常操作数据库带来的性能下降
  /// </summary>
  /// <returns>加载成功后返回true</returns>
  private bool LoadData(){
   try{
    using(SqlConnection conn  =new SqlConnection("database=CategoryTest;uid=sa;pwd=sa")){
     conn.Open();
     string sql="select * from  Categories";
     using(SqlDataAdapter da = new SqlDataAdapter(sql,conn)){
      da.Fill(dt);
     }
    }
    return true;
   }catch(Exception ex){
    Console.WriteLine(ex.Message);
    Console.WriteLine(ex.StackTrace);
    //MessageBox.Show("读取数据出错");
    return false;
   }
  }

  private void tvCategory_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e) {
   //遍历所有支节点
   //如果e.node为父节点,则将会加载所有支节点下面的叶节点(第三级)
   for(int i=0;i<e.Node.Nodes.Count;i++){
    //加载支节点下的所有支节点(第三级节点)
    AddChildNode(e.Node.Nodes[i]);
   }
  }
 }
}

原文地址:https://www.cnblogs.com/seerlin/p/1229919.html