數據庫結構
id:int類型,主鍵,自增列;
Name:char類型;
paraid:int類型
窗台拖入控件treeview。
1.版本1
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace _1.多級菜單 { public partial class Form1 : Form { //獲取鏈接 string ConnString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnSring"].ToString(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.LoadData(null); } /// <summary> /// 載入tn的所有子節點,如果tn=null,說明是跟節點 /// </summary> /// <param name="tn"></param> private void LoadData(TreeNode tn) { if (tn == null) { //為空說明是根節點,添加節點時直接在控件的Nodes屬性上添加就行了 using (SqlConnection conn = new SqlConnection(ConnString)) { //查找根節點 所以parenti=0 string sql = "select * from Table_Tree where parentid=0"; using (SqlCommand cmd = new SqlCommand(sql, conn)) { conn.Open(); using (SqlDataReader dr = cmd.ExecuteReader()) { while (dr.Read()) { TreeNode cNode = new TreeNode(); cNode.Text = dr["name"].ToString(); cNode.Tag = dr["Id"];//tag沒有意義,不被現實出來,所以就存儲id treeView1.Nodes.Add(cNode);//節點加到treeview LoadData(cNode); } } } } } else { //參數tn!=null 那就是說要找tn的所有子節點,並做為tn的子節點.怎么在tn這個節點上添加子節點呢? tn.Nodes.Add(cNode); using (SqlConnection conn = new SqlConnection(ConnString)) { //查找根節點 所以parenti=0 string sql = "select * from Table_Tree where parentid=@id"; using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@Id", tn.Tag);//tn是TreeNode對象 conn.Open(); using (SqlDataReader dr = cmd.ExecuteReader()) { while (dr.Read()) { TreeNode cNode = new TreeNode(); cNode.Text = dr["name"].ToString(); cNode.Tag = dr["Id"];//tag沒有意義,不被現實出來,所以就存儲id tn.Nodes.Add(cNode); LoadData(cNode); } } } } } } } }
運行結果:
2.版本2(數據庫相同)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace _02Tree { public partial class Form1 : Form { string ConnString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnString"].ToString(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.LoadData(null); } /// <summary> /// 載入tn的所有子節點,如果tn=null,說明載的是根節點 /// </summary> private void LoadData(TreeNode tn) { //獲得要添加的節點 List<TblTree> addNodes = this.GetNodesByParentId(tn == null ? 0 : Convert.ToInt32(tn.Tag)); foreach (var oneNode in addNodes) { TreeNode ctNode = new TreeNode(); ctNode.Text = oneNode.Name; ctNode.Tag = oneNode.Id; if (tn == null) { //如果是要節點,添加到控件上 treeView1.Nodes.Add(ctNode); } else { //如果tn不為null,說明要為tn添加子節點,所以我們就添加到tn上 tn.Nodes.Add(ctNode); } this.LoadData(ctNode);//調用自己,為ctNode添加子節點 } } private List<TblTree> GetNodesByParentId(int parentId) { List<TblTree> allNodes = new List<TblTree>(); string sql = "select * from Table_Tree where parentid=@id"; SqlDataReader dr = CommonCode.Sqlhelper.ExecuteReader(sql, new SqlParameter("@id", parentId)); while (dr.Read()) { TblTree oneNode = new TblTree(); oneNode.Name = dr["name"].ToString(); oneNode.Id = Convert.ToInt32(dr["id"]); oneNode.Parentid = parentId; allNodes.Add(oneNode); } dr.Close(); return allNodes; } } }
運行效果圖:
還有TblTree類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace _02Tree { public class TblTree { int id; public int Id { get { return id; } set { id = value; } } string name; public string Name { get { return name; } set { name = value; } } int parentid; public int Parentid { get { return parentid; } set { parentid = value; } } } }
數據庫通用公共類:版本1和版本2通用
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Text; namespace CommonCode { public static class Sqlhelper { private static readonly string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString; //執行數據庫無非就是執行cmd的以下方法 //1. ExecuteNonQuery 執行一個insert update delete public static int ExecuteNonQuery(string sql, params SqlParameter[] parameters) { using (SqlConnection conn = new SqlConnection(ConnectionString)) { using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddRange(parameters); conn.Open(); return cmd.ExecuteNonQuery(); } } } //2.ExecuteScaler 返回結果集的第一行第一列 public static object ExecuteScaler(string sql, params SqlParameter[] parameters) { using (SqlConnection conn = new SqlConnection(ConnectionString)) { using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddRange(parameters); conn.Open(); return cmd.ExecuteScalar(); } } } //3.ExecuteReader 返回一個Reader對象,用於讀於多行多列數據 //在數據庫上產生一個結果集,每次Read,從數據庫服務器上讀取一條數據回來,所以使用Reader讀取數據,不能與數據庫斷開連接. public static SqlDataReader ExecuteReader(string sql, params SqlParameter[] parameters) { SqlConnection conn = new SqlConnection(ConnectionString); using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddRange(parameters); conn.Open(); try { //在sqlhelper中,由於dr在返回給用戶使用,所以注意dr不要使用using(){] SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); return dr; } catch (Exception ex) { conn.Close(); throw ex; } } } //4.執行一個sql語句,並把結果集放入本地的DataTable中.這里數據已 //經放到本地,斷開數據庫連接,還是可以訪問到數據的. public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters) { using (SqlConnection conn = new SqlConnection(ConnectionString)) { using (SqlDataAdapter da = new SqlDataAdapter(sql, conn)) { da.SelectCommand.Parameters.AddRange(parameters); DataTable dt = new DataTable(); //Fill方法其實執行的是da.SelectCommand中的sql語句,這里可以寫conn.open也可以不寫,如果不寫,da會自動連接數據庫 da.Fill(dt); return dt; } } } } }