概述:根據(jù)如下圖所示的數(shù)據(jù)庫中的數(shù)據(jù)表,生成樹形菜單

最后成果:

前期準(zhǔn)備
相關(guān)內(nèi)容主要分為兩部分:
- 數(shù)據(jù)庫連接相關(guān)知識
- 邏輯設(shè)計(jì)
(1)數(shù)據(jù)庫連接
ps:此處只涉及Sql Server數(shù)據(jù)庫連接 ,深入理解需要學(xué)習(xí)ADO.NET。先貼上此處代碼
/// <summary>
/// 連接數(shù)據(jù)庫,獲取數(shù)據(jù)
/// </summary>
/// <param name="pID">上一級id</param>
/// <returns></returns>
public static DataTable GetData(int pID)
{
string sqlStr = "select NodeID,NodeName from OA_Config.dbo.ds_main where ParentID = '" + pID + "'";//設(shè)置sql查詢語言
SqlConnection conn1 = new SqlConnection("server=改成自己服務(wù)器地址;database=master;uid=sa;pwd=123456");//連接數(shù)據(jù)庫
SqlDataAdapter sqlDataAdapter1 = new SqlDataAdapter(sqlStr, conn1);//創(chuàng)建數(shù)據(jù)適配器
DataTable dt = new DataTable(); //創(chuàng)建新的數(shù)據(jù)表,也可以創(chuàng)建DataSet
sqlDataAdapter1.Fill(dt); //將查詢的數(shù)據(jù)裝入數(shù)據(jù)表中
return dt; //返回得到的數(shù)據(jù)表
}
上面的代碼需要使用命名空間using System.Data.SqlClient; 無需自己手動加,先寫完上述代碼后VS會有提示信息,直接點(diǎn)就會自動加了。
如下圖,沒加命名空間時,代碼處會有紅色波浪線提示,單擊該處代碼,此處代碼左下角會有一個灰色的小頁面圖標(biāo),點(diǎn)擊后出現(xiàn)如下圖所示的提示,點(diǎn)擊選擇第一個就會自動在代碼最開始處添加命名空間。

附上一個翻譯版的ADO.NET概述,利于理解ADO.NET對象,其中詳細(xì)介紹了SqlConnection、SqlCommand、SqlDataAdapter等內(nèi)容:
ADO.NET概述
英文好的可以看原文:.net Framework
結(jié)合下面這篇博客,效果更好
再看ADO.NET
(2)邏輯設(shè)計(jì)
簡單提取數(shù)據(jù),生成樹形菜單,主要用到NodeID、NodeName和ParentID三列數(shù)據(jù)。在連接數(shù)據(jù)庫,獲取數(shù)據(jù)階段,傳入的參數(shù)是ParentID,當(dāng)然這個也是通過此處確定的。
根據(jù)數(shù)據(jù)表,如何才能區(qū)分哪個是根節(jié)點(diǎn),哪個是子節(jié)點(diǎn),誰前誰后,都通過ParentID來區(qū)分。下一級節(jié)點(diǎn)的ParentID是上一級的NodeID,重點(diǎn)抓住這處關(guān)系實(shí)現(xiàn)代碼的反復(fù)調(diào)用。下面是全部代碼。
private void FrmDsManage_Load(object sender, EventArgs e)
{
treeView1.ShowPlusMinus = true;//設(shè)置顯示加減號
addRootNode(-1); //設(shè)置根節(jié)點(diǎn)的初始值,來源數(shù)據(jù)庫中根節(jié)點(diǎn)自身設(shè)置的值,一般是-1或0
}
/// <summary>
/// 添加根節(jié)點(diǎn)
/// </summary>
/// <param name="parentID">上一級id</param>
public void addRootNode(int parentID)
{
DataTable dt1 = GetData(parentID); //獲取數(shù)據(jù)
if (dt1.Rows.Count > 0) //判斷獲取的表格是否有數(shù)據(jù)
{
foreach (DataRow dr in dt1.Rows) //循環(huán)查詢獲取表格的每行數(shù)據(jù)
{
TreeNode rootNode = new TreeNode(); //新建TreeNode對象實(shí)例
rootNode.Tag = Convert.ToInt32(dr["NodeID"]); //將節(jié)點(diǎn)id賦給TreeNode對象的tag屬性
rootNode.Text = dr["NodeName"].ToString(); //節(jié)點(diǎn)名稱賦給TreeNode對象的text屬性
treeView1.Nodes.Add(rootNode); //節(jié)點(diǎn)插入到treeView1對象中,此處treeView1是自己在winform窗體中的展現(xiàn)菜單的控件
addChildrenNode(rootNode); //通過傳入上一級節(jié)點(diǎn)調(diào)用添加子節(jié)點(diǎn)的代碼
}
}
}
/// <summary>
/// 添加子節(jié)點(diǎn)
/// </summary>
/// <param name="previousGradeNodes">上一級節(jié)點(diǎn)名稱</param>
public void addChildrenNode(TreeNode previousGradeNodes)
{
DataTable dt2 = GetData(Convert.ToInt32(previousGradeNodes.Tag));//上一級的id作為當(dāng)前級別的parentID
if (dt2.Rows.Count > 0)
{
foreach (DataRow dr in dt2.Rows)
{
TreeNode currentGradeNode = new TreeNode();
currentGradeNode.Tag = Convert.ToInt32(dr["NodeID"]);
currentGradeNode.Text = dr["NodeName"].ToString();
previousGradeNodes.Nodes.Add(currentGradeNode);
addChildrenNode(currentGradeNode);
}
}
}
/// <summary>
/// 連接數(shù)據(jù)庫,獲取數(shù)據(jù)
/// </summary>
/// <param name="pID">上一級id</param>
/// <returns></returns>
public static DataTable GetData(int pID)
{
string sqlStr = "select NodeID,NodeName from OA_Config.dbo.ds_main where ParentID = '" + pID + "'";//設(shè)置sql查詢語言
SqlConnection conn1 = new SqlConnection("server=服務(wù)器地址自己改;database=master;uid=sa;pwd=123456");//連接數(shù)據(jù)庫
SqlDataAdapter sqlDataAdapter1 = new SqlDataAdapter(sqlStr, conn1);//創(chuàng)建數(shù)據(jù)適配器
DataTable dt = new DataTable(); //創(chuàng)建新的數(shù)據(jù)表,也可以創(chuàng)建DataSet
sqlDataAdapter1.Fill(dt); //將查詢的數(shù)據(jù)裝入數(shù)據(jù)表中
return dt; //返回得到的數(shù)據(jù)表
}