65.9K
CodeProject 正在变化。 阅读更多。
Home

构建动态树

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.09/5 (4投票s)

2007年9月23日

CPOL

2分钟阅读

viewsIcon

36190

downloadIcon

910

你想构建一个动态菜单!? 你可以使用递归算法来解决这个问题。

Screenshot - tree.jpg

引言

当您构建应用程序或网站时,您想构建一个动态菜单,该菜单包含多个层级,具体取决于您的类别、子类别、产品,但您从未确切知道您的菜单有多少层级。现在,我将制作这个来向您展示解决这个问题的方法。

背景

当您必须制作一个商店的网站时。这家商店有很多产品,他们希望将其产品安排到类别、子类别、产品到许多层级。他们希望使其具有动态性,他们可以创建一个新的层级(子-子类别,...),您必须让他们这样做。当您开发时,您不知道可以构建多少层级的菜单。

要解决这个问题,您应该使用递归算法。

在这里,我使用 WinForm 中的 TreeView 来演示这个。我将读取 Datatable 中的数据以构建一个动态树。此代码可在 ASP.NET 中使用。我使用 Visual Studio 2005 来开发它。

使用代码

首先,我将定义一个 DataTable 来存储菜单的 ID、PID(父 ID)、信息...
//
//  
    DataTable tbl;      
    DataColumn col;     
    private void InitTable()
        {
            tbl = new DataTable();

            col = new DataColumn("ID");
            tbl.Columns.Add(col);
            col = new DataColumn("PID");
            tbl.Columns.Add(col);
            col = new DataColumn("Info");
            tbl.Columns.Add(col);

            tbl.AcceptChanges();            
        } 



然后,我将为此表制作数据。此表存储菜单的信息。

//
    private void initTableData()
        {
            DataRow r;

            r = tbl.NewRow();
            r["ID"] = "0";
            r["PID"] = "-1";
            r["Info"] = "Root";
            tbl.Rows.Add(r);

    
            r = tbl.NewRow();
            r["ID"] = "1";
            r["PID"] = "0";
            r["Info"] = "Menu1";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "10";
            r["PID"] = "0";
            r["Info"] = "Menu10";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "2";
            r["PID"] = "0";
            r["Info"] = "Menu2";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "3";
            r["PID"] = "0";
            r["Info"] = "Menu3";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "4";
            r["PID"] = "1";
            r["Info"] = "Menu4";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "5";
            r["PID"] = "4";
            r["Info"] = "Menu5";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "6";
            r["PID"] = "5";
            r["Info"] = "Menu6";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "7";
            r["PID"] = "2";
            r["Info"] = "Menu7";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "11";
            r["PID"] = "6";
            r["Info"] = "Menu11";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "8";
            r["PID"] = "10";
            r["Info"] = "Menu8";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "9";
            r["PID"] = "3";
            r["Info"] = "Menu9";
            tbl.Rows.Add(r);

            r = tbl.NewRow();
            r["ID"] = "12";
            r["PID"] = "7";
            r["Info"] = "Menu12";
            tbl.Rows.Add(r);
        }
// 

让我们开始构建这棵树!

我创建了一个方法来构建这棵树。这棵树有一个 "Root",ID=0,PID=-1。这样,任何菜单的 PID=0 都是此菜单的子菜单,并且此 "Root" 的 PID=-1 没有父菜单。

我们将把这个 "Root" 添加到树中,并调用方法 initTreeView(TreeNode N)。我们认为所有子菜单都是一个 TreeNode,我们将把这个 TreeNode 添加到 "Root"。对于另一个节点,我们继续将其视为一个 "mini root",而此节点的其他子菜单是一个 "mini node",因此我们也会将其添加到这个 "mini root" 中。

    private void initTreeView(TreeNode N)
        {
            DataTable temp = new DataTable();
            col = new DataColumn("ID");
            temp.Columns.Add(col);
            col = new DataColumn("PID");
            temp.Columns.Add(col);
            col = new DataColumn("Info");
            temp.Columns.Add(col);
            temp.AcceptChanges();  
            
           
            string id = getID(N);            
            foreach (DataRow r1 in tbl.Rows)
            {
                if (r1["PID"].ToString() == id)
                {
                    DataRow r2 = temp.NewRow();
                    r2["ID"] = r1["ID"].ToString();
                    r2["PID"] = r1["PID"].ToString();
                    r2["Info"] = r1["Info"].ToString();
                    temp.Rows.Add(r2);
                    temp.AcceptChanges();
                }
            }

            foreach(DataRow r3 in temp.Rows)
            {
                TreeNode tn = new TreeNode();
                tn.Text = r3["Info"].ToString();
                initTreeView(tn);
                N.Nodes.Add(tn);
            }
        }

对于任何节点,我们将找到它的所有子节点(我定义了一个新的 DataTable:temp 来存储这些子节点),对于每个子节点,将继续调用方法 initTreeView() 来构建它。依此类推,我们将找到最小的菜单并将其添加到其父菜单。

关注点

通过一小段代码,我们已经构建了一个动态菜单。它制作起来很简单,易于记忆,并且可以应用于 WinForm 或 WebForm。
此算法可用于任何语言。

享受我的代码!感谢您的阅读!
如有任何问题或投诉,请通过以下方式联系我

姓名:Nguyen Anh Vu
电子邮件:nguyenanhvu.aiti@gmail.com
spiderman_anhvu@yahoo.com

© . All rights reserved.