实现树形菜单很多人使用递归来实现,这样效率比较低,如果你的数据结构是以下这种方式,可以试试这种方法:
数据结构(SQL2005):
表名:SysFun
NodeId(int) DisplayName(varchar) ParentNodeId(int)
101 他爹1号 0
102 他爹2号 0
101001 他儿1号 101
101002 他儿2号 101
102001 他女1号 102
102002 他女2号 102
102003 他女3号 102
存储过程:
CREATE PROCEDURE GetAllSysFun
AS
BEGIN
DECLARE @tab TABLE
(
NodeId varchar(50),
DisplayName varchar(50),
ParentNodeId int
)
INSERT INTO @tab SELECT NodeId, DisplayName, ParentNodeId FROM dbo.SysFun
SELECT NodeId, DisplayName, ParentNodeId FROM @tab ORDER BY NodeId
END
GO
查出的结果:
NodeId DisplayName ParentNodeId
101 他爹1号 0
101001 他儿1号 101
101002 他儿2号 101
102 他爹2号 0
102001 他女1号 102
102002 他女2号 102
102003 他女3号 102
如果SysFun表NodeId本身就是varchar类型就不用建临时表@tab了,直接排序
循环方法:
private void ShowTreeView()
{
int fatherNode = 0;//记录父节点Id
TreeNode treeNode = null;//父节点
TreeNode treeNodes = null;//子节点
IList<SysFun> listSysFuns = SysFunManager.GetAllSysFun();//查询
foreach (SysFun sysFun in listSysFuns)
{
if (sysFun.ParentNodeId == 0)
{
fatherNode = int.Parse(sysFun.NodeId);
treeNode = new TreeNode(sysFun.DisplayName, sysFun.NodeId.ToString(), "images/CloseTree.gif", null, "");
this.tvUserRightMenu.Nodes.Add(treeNode);
}
else if (sysFun.ParentNodeId == fatherNode)
{
treeNodes = new TreeNode(sysFun.DisplayName, sysFun.NodeId.ToString(), "images/OpenTree.gif", sysFun.NodeURL, "");
treeNode.ChildNodes.Add(treeNodes);
}
else
{
string valuePath = GetValuePath(sysFun.ParentNodeId);
treeNode = this.tvUserRightMenu.FindNode(valuePath);
fatherNode = sysFun.ParentNodeId;
treeNodes = new TreeNode(sysFun.DisplayName, sysFun.NodeId.ToString(), "images/OpenTree.gif", sysFun.NodeURL, "");
treeNode.ChildNodes.Add(treeNodes);
}
}
}
private string GetValuePath(int parentNodeId)
{
StringBuilder sb = new StringBuilder();
while (parentNodeId != 0)
{
sb.Insert(0, parentNodeId);
sb.Insert(0, this.tvUserRightMenu.PathSeparator);
parentNodeId /= 1000;
}
return sb.ToString().Substring(1);
}