.net中显示的树形结构,每次打开页面都遍历一边,输入的节点越多,IE占用的内存就越大,速度也就越慢。应该用什么方法可以解决呢?怎么限制遍历深度?谢谢!
解决方案 »
- 请教:c# winform程序少量数据的存储,使用文件存储还是access数据库?
- 求类似datetimepicker效果的控件
- wpf鼠标拖动控件问题
- 真诚请教:c# winfrom中datagirdview 依据第一列单元格中的数据判断来合并后面列中单元格 请大侠们解决一下 谢谢!
- 关于COOKIE的怪问题!~
- UTF8Encoding.GetBytes(string)的byte数组长度问题
- 在c#中可以启动非.exe或.com文件吗?如何启动?
- 怎样在VS.NET中注册外部插件的帮助?也就是说在VS.NET里按F1键能搜索到外部帮助?急!!
- C# Windows窗体应用程序调试出错,“Windows 已在 xxx.exe 中触发一个断点……”
- 一个简单的winForm问题,在主窗体树形菜单部分,是放在另外一个窗体中的,通过new这个窗体在主窗体中显示,问题是..............
- (请大家讨论)常用的条码信息采集设备及应用领域(在线等)
- 求救 WPF关于ListBox 样式 功能延伸
用异步加载,一次不要将所有的节点都遍历,只要遍历一级菜单即可,点击某个一级菜单的时候再用异步加载它下面的二级菜单 用递归。
1 先加载第一级节点, 并订阅SelectNodeChanged事件
2 在SelectNodeChanged事件中, 检查子节点是否已经加载, 如果没有加载, 加载子节点, 订阅SelectNodeChanged事件。如果已经加载, 就无需重新加载。
【签名】每个月总有那么几天,您的网络会受到黑客的攻击?坐立不安,烦躁无力,使用我和human开发的“月月舒”防火墙,超轻超薄,易于携带,提供由内到外的全方位保护,即使流量再大,也可以冲浪自如,再也不用担心侧漏啦。
http://webtrados.008.net 网络小筑,常来坐坐。
严格来说, 不应该叫做异步加载, 异步加载跟多线程有关。
我们所讨论的只是延迟加载, 就是,用到的时候再加载。
省市联动的做法跟加载TreeView基本类似, 因为两个带有父子关系的列表框其实跟TreeView没有很大区别。区别是: 联动列表的子列表每次都要变化, 而TreeView不用。 如果要求好的用户体验, 可以用Ajax处理联动列表。
哦我这里省市是用TreeView做的,想问下gentle_wolf 省市联动的做法跟加载TreeView基本类似是什么意思?难道不是用TreeView?
这不就解决了
恩是来自SQL
绑定的话很限制灵活性的
你OVERWRITE TREEVIEW
定义好每个节点就OK了
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Web.UI.WebControls;
using EastWind.Exceptions;namespace Web.Common.Utility
{
public delegate void TreeNodeLoadEventHandler(TreeNode tnCurrent, DataRow drCurrent);
public delegate void TreeNodeViewEventHandler(TreeNode tnCurrent, params object[] userData); public static class TreeHelper
{
/// <summary>
/// 展开父辈节点
/// </summary>
public static void ExpandAncestor(TreeNode tnCurrent)
{
while (tnCurrent.Parent != null)
{
tnCurrent.Expand();
tnCurrent = tnCurrent.Parent;
}
} /// <summary>
/// 遍历树的节点
/// </summary>
/// <param name="treeView"></param>
public static void IterateTreeNode(TreeView treeView,TreeNodeViewEventHandler hanlder,object[] userData)
{
foreach (TreeNode tnRoot in treeView.Nodes)
{
hanlder(tnRoot,userData);
IterateTreeNode(tnRoot, hanlder, userData);
}
} /// <summary>
/// 设置树节点的行为
/// </summary>
/// <param name="treeView"></param>
/// <param name="tnsa"></param>
public static void SetTreeViewSelectAction(TreeView treeView, TreeNodeSelectAction tnsa)
{
IterateTreeNode(treeView, new TreeNodeViewEventHandler(SetSelectTreeNodeAction), new object[] { tnsa });
} /// <summary>
/// 设置树节点的行为
/// </summary>
/// <param name="node"></param>
/// <param name="data"></param>
private static void SetSelectTreeNodeAction(TreeNode node, object[] data)
{
node.SelectAction = (TreeNodeSelectAction)data[0];
} /// <summary>
/// 遍历当前节点的子节点
/// </summary>
/// <param name="tnCurrent"></param>
/// <param name="hanlder"></param>
public static void IterateTreeNode(TreeNode tnCurrent, TreeNodeViewEventHandler hanlder, object[] userData)
{
foreach (TreeNode child in tnCurrent.ChildNodes)
{
hanlder(child,userData);
IterateTreeNode(child, hanlder,userData);
}
} /// <summary>
/// 加载数据到树视图中,value存放节点ID,text存放节点名称
/// </summary>
/// <param name="treeView">将被加载数据的树视图</param>
/// <param name="dtSource">源数据表</param>
/// <param name="parentColName">父列的名称</param>
/// <param name="childColName">子列的名称</param>
/// <param name="nodeNameCol">节点名称列名称</param>
/// <param name="rootID">跟节点的父节点id</param>
/// <param name="loaded">节点加载后调用用户方法</param>
public static void LoadData2TreeView(TreeView treeView, DataTable dtSource, string parentColName, string childColName, string nodeNameCol, object rootID, TreeNodeLoadEventHandler loaded)
{
DataRow[] layer1Nodes = SelectDataRow(dtSource.DefaultView, parentColName , rootID);
foreach (DataRow layer1Node in layer1Nodes)
{
TreeNode tnRoot = new TreeNode(); tnRoot.Value = layer1Node[childColName].ToString();
tnRoot.Text = layer1Node[nodeNameCol].ToString(); treeView.Nodes.Add(tnRoot); if (loaded != null)
{
loaded(tnRoot, layer1Node);
} LoadData2TreeNode(layer1Node[childColName],tnRoot, dtSource, parentColName, childColName, nodeNameCol, loaded);
}
} /// <summary>
/// 加载数据到树节点中,value存放节点ID,text存放节点名称
/// </summary>
/// <param name="parentID">父节点id对象</param>
/// <param name="tnParent">父节点名称</param>
/// <param name="dtSource">源数据表</param>
/// <param name="parentColName">父列的名称</param>
/// <param name="childColName">子列的名称</param>
/// <param name="nodeNameCol">节点名称列名称</param>
/// <param name="loaded">节点加载后调用用户方法</param>
public static void LoadData2TreeNode(object parentID, TreeNode tnParent, DataTable dtSource, string parentColName, string childColName, string nodeNameCol,TreeNodeLoadEventHandler loaded)
{
DataRow[] childRows = SelectDataRow(dtSource.DefaultView, parentColName ,parentID);
foreach (DataRow childRow in childRows)
{
TreeNode tnChild = new TreeNode(); tnChild.Value = childRow[childColName].ToString();
tnChild.Text = childRow[nodeNameCol].ToString(); tnParent.ChildNodes.Add(tnChild); if (loaded != null)
{
loaded(tnChild, childRow);
} LoadData2TreeNode(childRow[childColName], tnChild, dtSource, parentColName, childColName, nodeNameCol, loaded);
}
} /// <summary>
/// 加载数据到树视图中,value存放节点ID,text存放节点名称
/// </summary>
/// <param name="treeView">将被加载数据的树视图</param>
/// <param name="dtSource">源数据表</param>
/// <param name="parentColName">父列的名称</param>
/// <param name="childColName">子列的名称</param>
/// <param name="nodeNameCol">节点名称列名称</param>
/// <param name="rootID">跟节点的父节点id</param>
public static void LoadData2TreeView(TreeView treeView, DataTable dtSource, string parentColName, string childColName, string nodeNameCol, object rootID)
{
LoadData2TreeView(treeView, dtSource, parentColName, childColName, nodeNameCol, rootID, null);
} /// <summary>
/// 加载数据到树节点中,value存放节点ID,text存放节点名称
/// </summary>
/// <param name="tnParent">父节点名称</param>
/// <param name="dtSource">源数据表</param>
/// <param name="parentColName">父列的名称</param>
/// <param name="childColName">子列的名称</param>
/// <param name="nodeNameCol">节点名称列名称</param>
public static void LoadData2TreeNode(object parentID, TreeNode tnParent, DataTable dtSource, string parentColName, string childColName, string nodeNameCol)
{
LoadData2TreeNode(parentID, tnParent, dtSource, parentColName, childColName, nodeNameCol, null);
} /// <summary>
/// 从数据视图中选择数据行
/// </summary>
/// <param name="view">源视图</param>
/// <param name="colName">条件列名称</param>
/// <param name="value">值</param>
/// <returns>复合条件的数据行</returns>
public static DataRow[] SelectDataRow(DataView view, string colName, object value)
{
return SelectDataRow(view, new string[] { colName }, new object[] { value });
} /// <summary>
/// 从数据视图中选择数据行
/// </summary>
/// <param name="view">源视图</param>
/// <param name="colName">条件列名称</param>
/// <param name="value">值</param>
/// <returns>复合条件的数据行</returns>
public static DataRow[] SelectDataRow(DataTable dtSource, string colName, object value)
{
return SelectDataRow(dtSource, new string[] { colName }, new object[] { value });
} /// <summary>
/// 从数据表中选择数据行
/// </summary>
/// <param name="dtSource">源数据表</param>
/// <param name="colNames">条件列名称列表</param>
/// <param name="values">值列表</param>
/// <returns>复合条件的数据行</returns>
public static DataRow[] SelectDataRow(DataTable dtSource, string[] colNames, object[] values)
{
return SelectDataRow(dtSource.DefaultView, colNames, values);
} /// <summary>
/// 从数据表中选择数据行
/// </summary>
/// <param name="view">源视图</param>
/// <param name="colNames">条件列名称列表</param>
/// <param name="values">值列表</param>
/// <returns>复合条件的数据行</returns>
public static DataRow[] SelectDataRow(DataView view, string[] colNames, object[] values)
{
if (colNames.Length != values.Length)
{
throw new EastWindException("列与值必须一一对应");
} List<DataRow> rowList = new List<DataRow>();
for (int i = 0, count = view.Count; i < count; i++)
{
bool suit = true;
for (int j = 0; j < colNames.Length; j++)
{
if (!view[i][colNames[j]].Equals(values[j]))
{
suit = false;
}
} if (suit)
{
rowList.Add(view[i].Row);
}
} return rowList.ToArray();
}
}
}
我想知道下代码里怎么控制递归的深度呢?
{
if( ++depth > 100)
{
throw new Exception("递归深度超过限制");
}
DataRow[] childRows = SelectDataRow(dtSource.DefaultView, parentColName ,parentID);
foreach (DataRow childRow in childRows)
{
TreeNode tnChild = new TreeNode(); tnChild.Value = childRow[childColName].ToString();
tnChild.Text = childRow[nodeNameCol].ToString(); tnParent.ChildNodes.Add(tnChild); if (loaded != null)
{
loaded(tnChild, childRow);
} LoadData2TreeNode(childRow[childColName], tnChild, dtSource, parentColName, childColName, nodeNameCol, loaded, depth);
}
}
想问下在.NET里TreeView哪里有这个功能?