Asp.net 2.0 的 TreeView 控件功能虽说强大,但其客户端控制很逊色,本文将讲解 TreeView 的客户端实现原理,并实现两个个性化操作:

  (1) 节点的全部打开和关闭;

 

  TreeNode Expand(or Collapse) all

 

  (2) 只打开一个节点(关闭其他兄弟节点)。


  just one node expanded(when a client expand one node all other will collaps)

 

  用记事本打开页面源代码,可以找到一下两个脚本引用:

<script src="/WebUI/WebResource.axd?d=RAQeBcDUNuP9iuS8q3tNEw2&amp;t=633300220640000000" type="text/javascript"></script>
<script src="/WebUI/WebResource.axd?d=JuTdJhq3NM8Jq_RhssAkEg2&amp;t=633300220640000000" type="text/javascript"></script>

 

  将"/WebUI/WebResource.axd?d=RAQeBcDUNuP9iuS8q3tNEw2&t=633300220640000000"拷到地址栏尾,下载脚本,并以 .js 命名,另一个同样操作。分析第二个脚本文件,可以看到TreeView的很多客户端函数,其中关键的一个 TreeView_ToggleNode 就是客户端点击时触发的事件。

  要想做个性化的操作,就得从 TreeView_ToggleNode 事件下手。我们无法更改.net封装好的脚本,只有“重写”。所谓的重写就是在原来的函数之后添加一个同名函数(因为js对于同名函数只调用最后一个)。

  TreeView_ToggleNode 的原函数:


  function TreeView_ToggleNode(data, index, node, lineType, children) {
  var img = node.childNodes[0];
  var newExpandState;
  try {
  if (children.style.display == "none") {
  children.style.display = "block";
  newExpandState = "e";
  if ((typeof(img) != "undefined") && (img != null)) {
  if (lineType == "l") {
  img.src = data.images[15];
  }
  else if (lineType == "t") {
  img.src = data.images[12];
  }
  else if (lineType == "-") {
  img.src = data.images[18];
  }
  else {
  img.src = data.images[5];
  }
  img.alt = data.collapseToolTip.replace(/\{0\}/, TreeView_GetNodeText(node));
  }
  }
  else {
  children.style.display = "none";
  newExpandState = "c";
  if ((typeof(img) != "undefined") && (img != null)) {
  if (lineType == "l") {
  img.src = data.images[14];
  }
  else if (lineType == "t") {
  img.src = data.images[11];
  }
  else if (lineType == "-") {
  img.src = data.images[17];
  }
  else {
  img.src = data.images[4];
  }
  img.alt = data.expandToolTip.replace(/\{0\}/, TreeView_GetNodeText(node));
  }
  }
  }
  catch(e) {}
  data.expandState.value = data.expandState.value.substring(0, index) + newExpandState + data.expandState.value.slice(index + 1);
  }


  1. 节点的全部打开和关闭:


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>LeftMenu_Tree</title>
</head>
<body bgcolor="#DDEDFD">
    <form id="form1" runat="server">
        <a href="javascript:TreeviewExpandCollapseAll('<%=TreeView1.ClientID%>', true)">Expand
            All</a> <a href="javascript:TreeviewExpandCollapseAll('<%=TreeView1.ClientID%>', false)">
                Collapse All</a>
        <asp:TreeView ID="TreeView1" SkinID="tvClass" runat="server" ShowLines="true" NodeWrap="false">
        </asp:TreeView>
    </form>
</body>
</html>

<script language="javascript">
//-----------------------------------------------------------------------------
function $(s){return document.getElementById(s);}
function isNull(_sVal){return (_sVal == "" || _sVal == null || _sVal == "undefined");}

function TreeviewExpandCollapseAll(treeViewId, expandAll)
{
    var displayState = (expandAll == true ? "none" : "block");
    var treeView = $(treeViewId);
    if(treeView)
    {
        var treeLinks = treeView.getElementsByTagName("a");


        var nodeCount = treeLinks.length;
        var flag = true;
        for(i=0;i<nodeCount;i++)
        {
            if(treeLinks[i].firstChild.tagName)
            {
                if(treeLinks[i].firstChild.tagName.toLowerCase() == "img")
                {
                    var node = treeLinks[i];
                    var level = parseInt(node.id.substr(node.id.length - 1),10);
                    var childContainer = GetParentByTagName("table", node).nextSibling;
                    if(!isNull(childContainer))
                    {
                        if(flag)
                        {
                            if(childContainer.style.display == displayState)
                            {
                                TreeView_ToggleNode(eval(treeViewId +"_Data"),level,node,'r',childContainer);
                            }
                            flag = false;
                        }
                        else
                        {
                            if(childContainer.style.display == displayState)
                            {
                                TreeView_ToggleNode(eval(treeViewId +"_Data"),level,node,'l',childContainer);
                            }

                        }
                    }
                }
            }
        }//for loop ends
    }
}

function GetParentByTagName(parentTagName, childElementObj)
{
    var parent = childElementObj.parentNode;
    while(parent.tagName.toLowerCase() != parentTagName.toLowerCase())
    {
        parent = parent.parentNode;
    }
    return parent;


}
//-----------------------------------------------------------------------------
</script>

 

 

  2. 只打开一个节点(关闭其他兄弟节点)

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>LeftMenu_Tree</title>
</head>
<body bgcolor="#DDEDFD">
    <form id="form1" runat="server">
        <a href="javascript:TreeviewExpandCollapseAll('<%=TreeView1.ClientID%>', true)">Expand
            All</a> , <a href="javascript:TreeviewExpandCollapseAll('<%=TreeView1.ClientID%>', false)">
                Collapse All</a>
        <asp:TreeView ID="TreeView1" SkinID="tvClass" runat="server" ShowLines="true" NodeWrap="false">


        </asp:TreeView>
    </form>
</body>
</html>

<script language="javascript">
//2. 只打开一个节点(关闭其他兄弟节点)------------------------------------------
function TreeView_ToggleNode(data, index, node, lineType, children) 
{
    var img = node.childNodes[0];
    var newExpandState;
    try {
        //***折叠兄弟节点------------------------
        CollapseBrothers(data,children);
        //---------------------------------------
            
        if (children.style.display == "none") 
        {
            children.style.display = "block";
            newExpandState = "e";
            if ((typeof(img) != "undefined") && (img != null)) 
            {
                if (lineType == "l") 
                {
                    img.src = data.images[15];
                }

                else if (lineType == "t") 
                {
                    img.src = data.images[12];
                }
                else if (lineType == "-") 
                {
                    img.src = data.images[18];
                }

                else 
                {
                    img.src = data.images[5];
                }
                img.alt = data.collapseToolTip.replace(/\{0\}/, TreeView_GetNodeText(node));
            }
        }
        else 
        {
            children.style.display = "none";


            newExpandState = "c";
            if ((typeof(img) != "undefined") && (img != null)) 
            {
                if (lineType == "l") 
                {
                    img.src = data.images[14];
                }
                else if (lineType == "t") 

                {
                    img.src = data.images[11];
                }
                else if (lineType == "-") 
                {
                    img.src = data.images[17];
                }
                else 
                {


                    img.src = data.images[4];
                }
                img.alt = data.expandToolTip.replace(/\{0\}/, TreeView_GetNodeText(node));
            }
        }
    }
    catch(e) {}
    data.expandState.value =  data.expandState.value.substring(0, index) + newExpandState + data.expandState.value.slice(index + 1);
}

//折叠兄弟节点
function CollapseBrothers(data,childContainer)
{
    var parent = childContainer.parentNode;   
    for(i=0; i< parent.childNodes.length; i++)
    {
        if(parent.childNodes[i].tagName.toLowerCase() =="div")
        {
            if(parent.childNodes[i].id != childContainer.id)
            {
                parent.childNodes[i].style.display = "none"
            }
        }
        else if(parent.childNodes[i].tagName.toLowerCase() =="table")
        {
            var treeLinks = parent.childNodes[i].getElementsByTagName("a");            
            if(treeLinks.length > 2)
            {
                var j=0;
                if(treeLinks[j].firstChild.tagName)
                {
                    if(treeLinks[j].firstChild.tagName.toLowerCase() == "img")
                    {
                        var img = treeLinks[j].firstChild;

                        if(i==0) 
                            img.src = data.images[8];
                        else if(i==parent.childNodes.length-2) 
                            img.src = data.images[14];
                        else 
                            img.src = data.images[11];
                    }
                }    
            }
        }        
    }
}
//-----------------------------------------------------------------------------
</script>