asp.net循环递归加载树的优化方法~~~~~~~~求解~~~~~~~~~~~~~~~~~~

fwqkey 2009-04-14 06:50:30

public void CreateTreeNode(TreeNodeCollection nodes, DataTable dt, string curID, bool lb_sort, bool lb_expanded)
{
string ls_sort;
if (lb_sort == true)
{
ls_sort = "ASC";
}
else
{
ls_sort = "DESC";
}

//清空树中所有节点,以免出现重复显示的树节点
nodes.Clear();

// 创建一个空行记录
DataRow[] rows = null;
if (curID == null)
{
//查询出该树最上面一层的节点
rows = dt.Select("Convert(PARENTID, 'System.String') = '-1'", "XH " + ls_sort + "");//"[PARENTID] = -1"
}
else
{
//取出以该节点为父节点的所有节点
rows = dt.Select("Convert(PARENTID, 'System.String') = '" + curID + "'", "XH " + ls_sort + "");
}

// 循环赋值
foreach (DataRow row in rows)
{
//添加树的节点
TreeNode node = new TreeNode();
node.Value = row["ID"].ToString();
node.Text = row["NAME"].ToString();
node.SelectAction = TreeNodeSelectAction.Select;
node.Expanded = lb_expanded;

nodes.Add(node);
node.ImageUrl = "../addon/imgs/folder.gif";

CreateTreeNode(node.ChildNodes, dt, node.Value, lb_sort, lb_expanded);
//递归调用,创建树
this.CreateTreeNode(node.ChildNodes, dt, node.Value, lb_sort, lb_expanded);
}
}

在上面代码中最后的代码(如下)此代码有高手能优化下吗?这采用递归调用的方法,用现在这种方法打开页面加载树的速度会很慢,希望优化下此代码来提高加载树的速度。
//递归调用,创建树
this.CreateTreeNode(node.ChildNodes, dt, node.Value, lb_sort, lb_expanded);


...全文
397 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
fwqkey 2009-04-21
  • 打赏
  • 举报
回复
谢谢。。
chenwei175528 2009-04-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 fwqkey 的回复:]
引用 7 楼 Lxpd 的回复:
先加载一级结点,点击后再去加载二级节点
js代码怎么去实现这功能?
[/Quote]

用ajax 具体的不会...
chenwei175528 2009-04-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 Lxpd 的回复:]
先加载一级结点,点击后再去加载二级节点
[/Quote]

up
zhangxia_dct 2009-04-15
  • 打赏
  • 举报
回复
private SqlDataAdapter sda;
BaseClass.BaseClass baseclass = new HRP.BaseClass.BaseClass();
BaseClass.SqlClass sqlclass = new HRP.BaseClass.SqlClass();
private DataTable tblinfo = new DataTable();
private void frmDept_Load(object sender, EventArgs e)
{
this.sda = sqlclass.sqlsda("SELECT * FROM tb_dept ORDER BY DeptId");
this.sda.Fill(tblinfo);//读入数据
DataTable temptbl = tblinfo.Copy();//将部门表另存一份为temptbl
DataView viewinfo = new DataView(temptbl);
viewinfo.RowFilter = "DeptID = 1";
//将数据集中的所有记录逐个根据他们之间的关系添加到树形表中去
if (viewinfo.Count > 0)
{
foreach (DataRowView myRow in viewinfo)
{
string strdeptName = myRow["DeptName"].ToString().Trim();
//此处是添加第一个节点“首席执行官”
this.trvDept.Nodes.Add(new TreeNode(strdeptName));
//此处初始化参数是第一个节点“首席执行官”,然后该函数会递归添加所有子节点
PopulateTreeView(strdeptName, trvDept.Nodes[0], myRow);
//trvDept.SelectedNode = trvDept.Nodes[0]; //选中第一个节点 获取设置选择的节点
}
}
}
private void PopulateTreeView(string parentPart, TreeNode parentNode, DataRowView parentRow)
{
string strdeptName = "";
DataTable temptbl = tblinfo.Copy();
DataView viewinfo = new DataView(temptbl);
//筛选获得当前传递过来的节点的子项,并将其添加到树形图中
//判断方法是凡parentIndex等于传递过来的节点的absIndex的,就是该节点的子项
viewinfo.RowFilter = "ParentIndex = '" + parentRow["DeptID"].ToString().Trim() + "'";
//递归的添加每一个节点的所有子节点
foreach (DataRowView myRow in viewinfo)
{
strdeptName = myRow["DeptName"].ToString().Trim();
TreeNode myNode = new TreeNode(strdeptName);
parentNode.Nodes.Add(myNode);
//函数递归调用,将所有节点按顺序添加完毕
PopulateTreeView(strdeptName, myNode, myRow);
}
}
fwqkey 2009-04-15
  • 打赏
  • 举报
回复
大家贴点代码。
fwqkey 2009-04-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 Lxpd 的回复:]
先加载一级结点,点击后再去加载二级节点
[/Quote]js代码怎么去实现这功能?
Lxpd 2009-04-15
  • 打赏
  • 举报
回复
先加载一级结点,点击后再去加载二级节点
fwqkey 2009-04-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 SuperMan_ 的回复:]
建议楼主用ajax做.如果是.net2003的话很好办,如果是.net2005的话,得重写已经封装的脚本函数,
利用脚本函数的调用原则,如果有两个同名函数,会调用最后一个.
[/Quote]
ajax不太会。我用的是.net2005,。你有没有什么好的例子代码?或者不麻烦的话写点代码我看下。谢谢
Sysping1 2009-04-15
  • 打赏
  • 举报
回复
续上...
/// <summary>
/// 权限链节点
/// </summary>
public class PermissonLink
{
public static string Root = "__Root__";
public static string KeySeparator = "->";
public static string PermitField = "IsPermit";
public static string KeyField = "SystemObject_Code";
public static string NameField = "SystemObject_Name";
public static string ParentField = "SystemObject_CodeParent";

public int Level = 0;
public string Key = Root;
public string Code = Root;
public string Name = Root;
public bool IsPermit = true;
public string CodeParent = Root;
public PermissonLink Parent = null;
public readonly IDictionary<string, bool> ChildrenPermisson = new Dictionary<string, bool>();
public readonly IDictionary<string, PermissonLink> Childrens = new Dictionary<string, PermissonLink>();
public PermissonLink()
{ }

/// <summary>
/// Resets this instance.
/// </summary>
public void Reset()
{
foreach(PermissonLink child in this.Childrens.Values)
{
child.Reset();
}
this.ChildrenPermisson.Clear();
this.Childrens.Clear();
}
}
Sysping1 2009-04-15
  • 打赏
  • 举报
回复
构造权限树的方法,希望对你有帮助!

/// <summary>
/// Fills the permission dict.
/// 权限表填充到权限链表[递归]
/// </summary>
/// <param name="permissionTbl">The permission TBL.</param>
private static void CreatePermissonLink(PermissonLink permissonLink, DataTable permissionTbl)
{
if (permissionTbl == null) return;

bool isNotRoot = true;
string oldRowFilter = permissionTbl.DefaultView.RowFilter;
if (PermissonLink.Root.Equals(permissonLink.Code))
{
permissionTbl.DefaultView.RowFilter = PermissonLink.ParentField + "=" + PermissonLink.KeyField;
isNotRoot = false;
}
else
{
permissionTbl.DefaultView.RowFilter =
PermissonLink.ParentField + "='" + permissonLink.Code + "'" +
" And " + PermissonLink.KeyField + "<>'" + permissonLink.Code + "'";
}

try
{
if (permissionTbl.DefaultView.Count > 0)
{
object value = null;
string key = string.Empty;
PermissonLink newPermissonLink = null;
foreach (DataRowView dataRowView in permissionTbl.DefaultView)
{
value = dataRowView[PermissonLink.NameField] ?? string.Empty;
if (isNotRoot)
{
key = permissonLink.Key + PermissonLink.KeySeparator + value.ToString();
}
else
{
key = value.ToString();
}

if (!permissonLink.Childrens.ContainsKey(key))
{
newPermissonLink = new PermissonLink();
newPermissonLink.Level = permissonLink.Level + 1;
newPermissonLink.Name = value.ToString();
newPermissonLink.Key = key;

value = dataRowView[PermissonLink.KeyField] ?? string.Empty;
newPermissonLink.Code = Convert.ToString(value);

value = dataRowView[PermissonLink.ParentField] ?? string.Empty;
newPermissonLink.CodeParent = Convert.ToString(value);

value = (true.Equals(dataRowView[PermissonLink.PermitField])) ? true : false;
newPermissonLink.IsPermit = Convert.ToBoolean(value);

newPermissonLink.Parent = permissonLink;
}
else
{
newPermissonLink = permissonLink.Childrens[key];
}

permissonLink.Childrens.Add(newPermissonLink.Key, newPermissonLink);
permissonLink.ChildrenPermisson.Add(newPermissonLink.Key, newPermissonLink.IsPermit);

SecLocator.CreatePermissonLink(newPermissonLink, permissionTbl);
}
}
}
catch { }

permissionTbl.DefaultView.RowFilter = oldRowFilter;
}
Sysping1 2009-04-15
  • 打赏
  • 举报
回复
构建权限树的算法,希望对你有帮助!


/// <summary>
/// Fills the permission dict.
/// 权限表填充到权限链表[递归]
/// </summary>
/// <param name="permissionTbl">The permission TBL.</param>
private static void CreatePermissonLink(PermissonLink permissonLink, DataTable permissionTbl)
{
if (permissionTbl == null) return;

bool isNotRoot = true;
string oldRowFilter = permissionTbl.DefaultView.RowFilter;
if (PermissonLink.Root.Equals(permissonLink.Code))
{
permissionTbl.DefaultView.RowFilter = PermissonLink.ParentField + "=" + PermissonLink.KeyField;
isNotRoot = false;
}
else
{
permissionTbl.DefaultView.RowFilter =
PermissonLink.ParentField + "='" + permissonLink.Code + "'" +
" And " + PermissonLink.KeyField + "<>'" + permissonLink.Code + "'";
}

try
{
if (permissionTbl.DefaultView.Count > 0)
{
object value = null;
string key = string.Empty;
PermissonLink newPermissonLink = null;
foreach (DataRowView dataRowView in permissionTbl.DefaultView)
{
value = dataRowView[PermissonLink.NameField] ?? string.Empty;
if (isNotRoot)
{
key = permissonLink.Key + PermissonLink.KeySeparator + value.ToString();
}
else
{
key = value.ToString();
}

if (!permissonLink.Childrens.ContainsKey(key))
{
newPermissonLink = new PermissonLink();
newPermissonLink.Level = permissonLink.Level + 1;
newPermissonLink.Name = value.ToString();
newPermissonLink.Key = key;

value = dataRowView[PermissonLink.KeyField] ?? string.Empty;
newPermissonLink.Code = Convert.ToString(value);

value = dataRowView[PermissonLink.ParentField] ?? string.Empty;
newPermissonLink.CodeParent = Convert.ToString(value);

value = (true.Equals(dataRowView[PermissonLink.PermitField])) ? true : false;
newPermissonLink.IsPermit = Convert.ToBoolean(value);

newPermissonLink.Parent = permissonLink;
}
else
{
newPermissonLink = permissonLink.Childrens[key];
}

permissonLink.Childrens.Add(newPermissonLink.Key, newPermissonLink);
permissonLink.ChildrenPermisson.Add(newPermissonLink.Key, newPermissonLink.IsPermit);

SecLocator.CreatePermissonLink(newPermissonLink, permissionTbl);
}
}
}
catch { }

permissionTbl.DefaultView.RowFilter = oldRowFilter;
}

/// <summary>
/// 权限链节点
/// </summary>
public class PermissonLink
{
public static string Root = "__Root__";
public static string KeySeparator = "->";
public static string PermitField = "IsPermit";
public static string KeyField = "SystemObject_Code";
public static string NameField = "SystemObject_Name";
public static string ParentField = "SystemObject_CodeParent";

public int Level = 0;
public string Key = Root;
public string Code = Root;
public string Name = Root;
public bool IsPermit = true;
public string CodeParent = Root;
public PermissonLink Parent = null;
public readonly IDictionary<string, bool> ChildrenPermisson = new Dictionary<string, bool>();
public readonly IDictionary<string, PermissonLink> Childrens = new Dictionary<string, PermissonLink>();
public PermissonLink()
{ }

/// <summary>
/// Resets this instance.
/// </summary>
public void Reset()
{
foreach(PermissonLink child in this.Childrens.Values)
{
child.Reset();
}
this.ChildrenPermisson.Clear();
this.Childrens.Clear();
}
}
hzcong 2009-04-15
  • 打赏
  • 举报
回复
把数据库的信息读取出来搞成js数组或者json格式输出来.
然后在页面里用js循环.
fwqkey 2009-04-15
  • 打赏
  • 举报
回复
我在后台加载了所有的根节点,但是用来展开子节点的图标+号却没。。怎么回事??
fwqkey 2009-04-15
  • 打赏
  • 举报
回复
递归的方法我知道,不是加载很慢吗???
听你们又说ajax,但我ajax不怎么会呀。。。能不能贴点ajax实现的代码?
我的节点数据是从数据库读出来的。。有节点ID:parentID谢谢
快40的码农 2009-04-14
  • 打赏
  • 举报
回复
建议楼主用ajax做.如果是.net2003的话很好办,如果是.net2005的话,得重写已经封装的脚本函数,
利用脚本函数的调用原则,如果有两个同名函数,会调用最后一个.
wuyq11 2009-04-14
  • 打赏
  • 举报
回复
private void BindJG()
{
DataSet ds = new DataSet();
DB c = new DB();
ds = c.GetAll("Tb_xt_jg");
DataTable dtb = ds.Tables[0];
TreeNode root = new TreeNode();
root.Value = "0";
root.Text = "";
root.ImageUrl = "../images/folder.gif";
root.Expanded = true;
this.TreeView1.Nodes.Add(root);
initTree(dtb, "", root);
this.TreeView1.ExpandAll();
}
protected void initTree(DataTable dt, string nFatherid, TreeNode fatherNode)
{
DataView dv = new DataView(dt);

if (nFatherid == "")
dv.RowFilter = "depth='1'";
else
dv.RowFilter = "shangjjgbh='"+nFatherid+"'";
foreach (DataRowView Row in dv)
{
TreeNode node = new TreeNode();
if (fatherNode.Value == "0")//根节点
{
node.Value = Row["BH"].ToString();
node.Text = Row["mc"].ToString();
node.NavigateUrl = "";
node.ImageUrl = "../images/folder.gif";
fatherNode.ChildNodes.Add(node);
initTree(dt, Row["XTBH"].ToString(), node);
}
else
{
node.Text = Row["mc"].ToString();
node.Value = Row["BH"].ToString();
node.ImageUrl = "../images/jg.gif";
fatherNode.ChildNodes.Add(node);

}
}

}
fwqkey 2009-04-14
  • 打赏
  • 举报
回复
Ajax怎么做??
流浪河 2009-04-14
  • 打赏
  • 举报
回复
AJAX 50分啊 GG来了
fwqkey 2009-04-14
  • 打赏
  • 举报
回复
上面递归的方法多写了个。没注释。

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧