先说一下主要原理:
此处使用OnTreeNodePopulate事件并採用刷新的方式获取数据。第一次加载时获取根结点及其下两级结点,显示根结点和第一级结点,用第二级结点判断第一级结点是否含有结结点,并缓存第二级结点。下次逐级扩展时填加已缓存的第二级结点,并取得第二级结点的所有子结点。
说明:为什么要取第二级数据?
因为取得第一级数据后,您不知道是否有一下级。所以再取得第一级数据后的下一级数据,并用nodeDictionary 变量缓存所有第二级数据便于下次加载。
下次点击扩展时,先从变量中找此级的数据,找到后读取此级的下一级数据。
此处使用OnTreeNodePopulate事件并採用刷新的方式获取数据。第一次加载时获取根结点及其下两级结点,显示根结点和第一级结点,用第二级结点判断第一级结点是否含有结结点,并缓存第二级结点。下次逐级扩展时填加已缓存的第二级结点,并取得第二级结点的所有子结点。
说明:为什么要取第二级数据?
因为取得第一级数据后,您不知道是否有一下级。所以再取得第一级数据后的下一级数据,并用nodeDictionary 变量缓存所有第二级数据便于下次加载。
下次点击扩展时,先从变量中找此级的数据,找到后读取此级的下一级数据。
原理比较枯燥,用例子说明:
1、在页面中放入TreeView。并设置OnTreeNodePopulate事件和EnableClientScript属性。
<
asp:TreeView
ID
="tvDepartment"
runat
="server"
NodeIndent
="10"
OnTreeNodePopulate ="tvDepartment_TreeNodePopulate"
EnableClientScript ="False" >
< ParentNodeStyle ForeColor ="#5555DD" />
< SelectedNodeStyle BackColor ="#F2F6FB" />
< NodeStyle Font-Size ="12px" ForeColor ="Black" />
</ asp:TreeView >
OnTreeNodePopulate ="tvDepartment_TreeNodePopulate"
EnableClientScript ="False" >
< ParentNodeStyle ForeColor ="#5555DD" />
< SelectedNodeStyle BackColor ="#F2F6FB" />
< NodeStyle Font-Size ="12px" ForeColor ="Black" />
</ asp:TreeView >
此处说明一下EnableClientScript属性。如果EnableClientScript="True",当点击扩展结点时就调用客户端的角本,并不会回发,所取出的值与当前点的值不一致,造成成错误。所以此处要将EnableClientScript属性设为true。
2、后台代码(代码中涉及取数据的方法没有给出,您可以根据情况自己编写取数据方法)
代码
//
用于缓存数据
private static Dictionary < string , IList < PW_Department >> nodeDictionary = new Dictionary < string , IList < PW_Department >> ();
protected void Page_Load( object sender, EventArgs e)
{
if ( ! Page.IsPostBack)
{
nodeDictionary.Clear();
BindDepartmentTree( this .PwPid, " system " );
}
}
// 取得根目录的第一级数据
public void BindDepartmentTree( string pwPid, string departmentNo)
{
nodeDictionary.Clear();
UserPower userPower = new UserPower();
// 取得根目录
PW_Department pwSystem = userPower.GetParentDepartment(pwPid, departmentNo);
tvDepartment.Nodes.Clear();
if (pwSystem == null )
{
return ;
}
TreeNode tnRootNode = new TreeNode();
tnRootNode.Text = pwSystem.departmentName;
tnRootNode.Value = pwSystem.departmentNo;
// 取得根目录的第一级数据
IList < PW_Department > ilPwDepts = userPower.GetChildDepartment(PwPid, departmentNo);
if (ilPwDepts == null || ilPwDepts.Count < 1 )
{
return ;
}
foreach (PW_Department pdItem in ilPwDepts)
{
TreeNode tnNewNode = new TreeNode(pdItem.departmentName, pdItem.departmentNo);
// 取得第一级数据下的第二级数据
IList < PW_Department > ilChilldDepts = userPower.GetChildDepartment(PwPid, pdItem.departmentNo);
tnRootNode.ChildNodes.Add(tnNewNode);
if (ilChilldDepts == null || ilChilldDepts.Count < 1 )
{
}
else
{
// 设置父结点可以扩展
tnNewNode.PopulateOnDemand = true ;
tnNewNode.Expanded = false ;
nodeDictionary.Add(pdItem.departmentNo, ilChilldDepts);
}
}
tvDepartment.Nodes.Add(tnRootNode);
}
// TreeNodePopulate事件,用于分级取数据
protected void tvDepartment_TreeNodePopulate( object sender, TreeNodeEventArgs e)
{
// 取得当前点击的node的值
if (tvDepartment.SelectedNode != null )
{
string sValue = tvDepartment.SelectedNode.Value;
}
UserPower userPower = new UserPower();
string nodeID = e.Node.Value;
if (nodeDictionary != null )
{
if (nodeDictionary.Keys.Contains(nodeID))
{
if (nodeDictionary[nodeID].Count > 0 )
{
// 从缓存中取得当前结点的第一级结点
foreach (PW_Department pdItem in nodeDictionary[nodeID])
{
TreeNode tnNewNode = new TreeNode(pdItem.departmentName, pdItem.departmentNo);
// 取得当前结点第一级结点下的子结点
IList < PW_Department > ilPwDepts = userPower.GetChildDepartment(PwPid, tnNewNode.Value);
// 如果没有子结点,不可以扩展
if (ilPwDepts == null || ilPwDepts.Count < 1 )
{
tnNewNode.Expanded = false ;
tnNewNode.PopulateOnDemand = false ;
tnNewNode.SelectAction = TreeNodeSelectAction.Select;
e.Node.ChildNodes.Add(tnNewNode);
}
else
{
// 设置父结点可以扩展
tnNewNode.PopulateOnDemand = true ;
tnNewNode.Expanded = false ;
tnNewNode.SelectAction = TreeNodeSelectAction.Select;
e.Node.ChildNodes.Add(tnNewNode);
// 级存当前结点第一级结点下的子结点
nodeDictionary.Add(pdItem.departmentNo, ilPwDepts);
}
}
// 移除已展开的节点
nodeDictionary.Remove(nodeID);
}
}
}
}
private static Dictionary < string , IList < PW_Department >> nodeDictionary = new Dictionary < string , IList < PW_Department >> ();
protected void Page_Load( object sender, EventArgs e)
{
if ( ! Page.IsPostBack)
{
nodeDictionary.Clear();
BindDepartmentTree( this .PwPid, " system " );
}
}
// 取得根目录的第一级数据
public void BindDepartmentTree( string pwPid, string departmentNo)
{
nodeDictionary.Clear();
UserPower userPower = new UserPower();
// 取得根目录
PW_Department pwSystem = userPower.GetParentDepartment(pwPid, departmentNo);
tvDepartment.Nodes.Clear();
if (pwSystem == null )
{
return ;
}
TreeNode tnRootNode = new TreeNode();
tnRootNode.Text = pwSystem.departmentName;
tnRootNode.Value = pwSystem.departmentNo;
// 取得根目录的第一级数据
IList < PW_Department > ilPwDepts = userPower.GetChildDepartment(PwPid, departmentNo);
if (ilPwDepts == null || ilPwDepts.Count < 1 )
{
return ;
}
foreach (PW_Department pdItem in ilPwDepts)
{
TreeNode tnNewNode = new TreeNode(pdItem.departmentName, pdItem.departmentNo);
// 取得第一级数据下的第二级数据
IList < PW_Department > ilChilldDepts = userPower.GetChildDepartment(PwPid, pdItem.departmentNo);
tnRootNode.ChildNodes.Add(tnNewNode);
if (ilChilldDepts == null || ilChilldDepts.Count < 1 )
{
}
else
{
// 设置父结点可以扩展
tnNewNode.PopulateOnDemand = true ;
tnNewNode.Expanded = false ;
nodeDictionary.Add(pdItem.departmentNo, ilChilldDepts);
}
}
tvDepartment.Nodes.Add(tnRootNode);
}
// TreeNodePopulate事件,用于分级取数据
protected void tvDepartment_TreeNodePopulate( object sender, TreeNodeEventArgs e)
{
// 取得当前点击的node的值
if (tvDepartment.SelectedNode != null )
{
string sValue = tvDepartment.SelectedNode.Value;
}
UserPower userPower = new UserPower();
string nodeID = e.Node.Value;
if (nodeDictionary != null )
{
if (nodeDictionary.Keys.Contains(nodeID))
{
if (nodeDictionary[nodeID].Count > 0 )
{
// 从缓存中取得当前结点的第一级结点
foreach (PW_Department pdItem in nodeDictionary[nodeID])
{
TreeNode tnNewNode = new TreeNode(pdItem.departmentName, pdItem.departmentNo);
// 取得当前结点第一级结点下的子结点
IList < PW_Department > ilPwDepts = userPower.GetChildDepartment(PwPid, tnNewNode.Value);
// 如果没有子结点,不可以扩展
if (ilPwDepts == null || ilPwDepts.Count < 1 )
{
tnNewNode.Expanded = false ;
tnNewNode.PopulateOnDemand = false ;
tnNewNode.SelectAction = TreeNodeSelectAction.Select;
e.Node.ChildNodes.Add(tnNewNode);
}
else
{
// 设置父结点可以扩展
tnNewNode.PopulateOnDemand = true ;
tnNewNode.Expanded = false ;
tnNewNode.SelectAction = TreeNodeSelectAction.Select;
e.Node.ChildNodes.Add(tnNewNode);
// 级存当前结点第一级结点下的子结点
nodeDictionary.Add(pdItem.departmentNo, ilPwDepts);
}
}
// 移除已展开的节点
nodeDictionary.Remove(nodeID);
}
}
}
}