ASP.NET TreeView
级联选择问题
关于
ASP.NET TreeView
控件级联选择问题,网上有不少的解决办法。个人觉得给
TreeView
注册
onclick
事件是最好的办法。下面是用于级联选择的一个
JavaScript
方法,将此方法注册到
TreeView
的
onclick
即可实现级联选择:
function CheckSubNodes()
{
var obj = window.event.srcElement;
var TreeNodeFound = false;
var CheckedState;
if(obj.tagName=="INPUT"&&obj.type=="checkbox")
{
var TreeNode = obj;
CheckedState = obj.checked;
do
{
obj = obj.parentNode;
}
while(obj.tagName!="TABLE")
var parentTreeLevel = obj.rows[0].cells.length;
var parentTreeNode = obj.rows[0].cells[0];
var tables = obj.parentElement.getElementsByTagName("TABLE");
var numTables = tables.length;
if(numTables>=1)
{
for(var i=0;i<=numTables;i++)
{
if(tables[i]==obj)
{
TreeNodeFound = true;
i++;
if(i==numTables)
{
return;
}
}
if(TreeNodeFound==true)
{
var childTreeLevel = tables[i].rows[0].cells.length;
if (childTreeLevel > parentTreeLevel)
{
var cell = tables[i].rows[0].cells[childTreeLevel - 1];
var inputs = cell.getElementsByTagName("INPUT");
inputs[0].checked = CheckedState;
}
else
{
return;
}
}
}
}
}
}
说实话,这段JavaScript代码是比较冗长的,我建了一个页面,里面包含一个TreeView,用于测试此方法:
<
html
xmlns="http://www.w3.org/1999/xhtml" >
<
head
runat="server">
<title>TreeView
级联选择</title>
<
script
language="javascript">
function CheckSubNodes()
{
var obj = window.event.srcElement;
var TreeNodeFound = false;
var CheckedState;
if(obj.tagName=="INPUT"&&obj.type=="checkbox")
{
var TreeNode = obj;
CheckedState = obj.checked;
do
{
obj = obj.parentNode;
}
while(obj.tagName!="TABLE")
var parentTreeLevel = obj.rows[0].cells.length;
var parentTreeNode = obj.rows[0].cells[0];
var tables = obj.parentElement.getElementsByTagName("TABLE");
var numTables = tables.length;
if(numTables>=1)
{
for(var i=0;i<=numTables;i++)
{
if(tables[i]==obj)
{
TreeNodeFound = true;
i++;
if(i==numTables)
{
return;
}
}
if(TreeNodeFound==true)
{
var childTreeLevel = tables[i].rows[0].cells.length;
if (childTreeLevel > parentTreeLevel)
{
var cell = tables[i].rows[0].cells[childTreeLevel - 1];
var inputs = cell.getElementsByTagName("INPUT");
inputs[0].checked = CheckedState;
}
else
{
return;
}
}
}
}
}
}
</
script
>
</
head
>
<
body
>
<form id="form1" runat="server">
<div>
<asp:TreeView ID="TreeView1" runat="server" ShowCheckBoxes="All" ShowLines="True" onclick="CheckSubNodes()">
<Nodes>
<asp:TreeNode Text="
新建节点1"
Value="
新建节点1">
<asp:TreeNode Text="
新建节点1.1"
Value="
新建节点1.1">
<asp:TreeNode Text="
新建节点1.1.1"
Value="
新建节点1.1.1"></
asp
:
TreeNode
>
</asp:TreeNode>
</asp:TreeNode>
<asp:TreeNode Text="
新建节点2"
Value="
新建节点2">
<asp:TreeNode Text="
新建节点2.1"
Value="
新建节点2.1"></
asp
:
TreeNode
>
<asp:TreeNode Text="
新建节点2.2"
Value="
新建节点2.2"></
asp
:
TreeNode
>
</asp:TreeNode>
<asp:TreeNode Text="
新建节点3"
Value="
新建节点3">
<asp:TreeNode Text="
新建节点3.1"
Value="
新建节点3.1"></
asp
:
TreeNode
>
</asp:TreeNode>
<asp:TreeNode Text="
新建节点4"
Value="
新建节点4"></
asp
:
TreeNode
>
</Nodes>
</asp:TreeView>
</div>
</form>
</
body
>
</
html
>
测试时,点击“新建节点1.1”会出错(但此方法还是实现了功能,尽管出错了),在开启IE调试功能时会弹出错误提示,若没有开启IE调试状态栏也会出现错误提示。下面是我的一个方法:
function CheckSubNodes()
{
var obj = window.event.srcElement; //
获取事件对象的来源
var CheckState; //
定义一个变量,用于存储选中状态(true or false),以便于在子节点级联
if(obj.tagName=="INPUT"&&obj.type=="checkbox") //
如果事件的来源是checkbox
{
CheckState = obj.checked; //
获得该checkbox的选中状态
do
{
obj = obj.parentNode;
}
while(obj.tagName!="TABLE")
//
获得包含该checkbox的table,由于每个节点都在一个table中,因此相当于获取到节点
obj = obj.nextSibling; //获得该节点的兄弟节点
if(obj!=null&&obj.tagName=="DIV")
//
判断该节点是否为空以及是否为一棵子树,子树包含在DIV中(且在该节点的后一个节点中),
//而节点包含在table中
{
var inputs = obj.getElementsByTagName("INPUT");
//
获得该节点子树中的checkbox
for(var i=0;i<inputs.length;i++)
{
inputs[i].checked = CheckState;
//
遍历inputs,使子树的所有checkbox状态与该节点一致
}
}
}
}
与上一个方法比起来,这个方法比上一个简练(效率自然也高一些),且没有任何错误(在IE 7下测试)。要测试此方法,请将上述测试页面CheckSubNodes()方法替换为我的方法。