1 前言
用
.Net
做
Web
应用
,
有一个很大的苦恼就是没有太趁手的
TreeView
可用。微软的
TreeView
仅用作数据显示还行,但服务器控件不停的刷新太影响客户体验。商业化的
TreeView
(
obout treeview / FlyTreeView / Infragistics NetAdvantage Treeview
)都不错,特别是
obout treeview
短小精干讨人喜欢,但许可证是一个大障碍(公司一般不会花钱买的)。我一般而言,在
TreeView
上
做事情,用
checkbox
的时候较多,特别是父子节点的关联,因此,对
Microsoft TreeView
改造就从父子节点的关联开始。
2 ASP.Net 2.0 Treeview 简要分析
ASP.Net 2.0 Treeview
吹的很不错,但客户端操作几乎为零。微软实现了一些客户端用的
. TreeView.js
,还不公开,藏在
system.web.dll
中,以资源的方式通过
WebResource.axd
来向客户端释放。仔细分析一下
TreeView.js
,会发现微软为
TreeView
自动生成的
Html
脚本结构如下:
<div> //
树
<table/> //
节点
<div/> //
节点的子节点,里面的内容是一个或多个
<table/><div/>
</div>
因此,准确的说是
<table/><div/>
构成一个节点,但很难明确的在
DOM
中确定一个节点,原因如下:
1.
其
ID
或
Name
是顺序排列的,命名规则如下:
树
ID + “n” +
节点序号,例如
MyTreen0
商业的
TreeView
一般在
ID
中包含层次信息,如
: MyTreeNode1_1_2
表示树的
1.1.2
那个节点,分析起来很容易
2.
上面描述的节点命名的
ID
,是分配给
<table/>
里的
<A/>
也就是显示
加号
减号的那个链接元素,由于该元素在
<table/>
中,因此给分析带来了难度
3.
叶子节点没有上面所描述的
<table/>
里的那个
<A/>
,
无法分析(因此我自己
.
才会里出现
A
节点和
Input
节点,
A
节点就是有“树
ID + “n” +
节点序号”为
ID
的链接元素,
Input
节点是
<table/>
里的
Checkbox
,命名规则为:
树
ID + “n” +
节点序号
+ “CheckBox”
)
没办法,只有自己写JS函数来处理CheckBox的级联操作,其中用到了微软的TreeView.js 和 WebForm.js,下载链接: TreeView2.rar
加入方法如下:
* 为 TreeView 加入 OnClick 事件
* 为 TreeView 加入 OnClick 事件
直接在
TreeView的属性上加入:
OnClick="OnTreeNodeChecked()"
或者:
MyTree.Attributes.Add("OnClick", "OnTreeNodeChecked(event)");
*
这样写
OnClick
事件动作
<
. language
=
. type
=
"
text/.
"
>
function OnTreeNodeChecked()
{
var element = window.event.srcElement;
if (!IsCheckBox(element))
return;
var isChecked = element.checked;
var tree = TV2_GetTreeById(<%=SubSysTree.ClientID%>);
var node = TV2_GetNode(tree,element);
TV2_SetChildNodesCheckStatus(node,isChecked);
var parent = TV2_GetParentNode(tree,node);
TV2_NodeOnChildNodeCheckedChanged(tree,parent,isChecked);
}
< / .>
function OnTreeNodeChecked()
{
var element = window.event.srcElement;
if (!IsCheckBox(element))
return;
var isChecked = element.checked;
var tree = TV2_GetTreeById(<%=SubSysTree.ClientID%>);
var node = TV2_GetNode(tree,element);
TV2_SetChildNodesCheckStatus(node,isChecked);
var parent = TV2_GetParentNode(tree,node);
TV2_NodeOnChildNodeCheckedChanged(tree,parent,isChecked);
}
< / .>
这里是引用了一个外部js文件,如果只是要简单的选择父节点,同时下面子节点全部都全中,其实很简单,下面是我自己摘出来的一段代码。
function setChildrenNodesCheck()
{
var element = window.event.srcElement;
if(element.tagName=="INPUT")
{
var id=element.id.toLowerCase().replace("checkbox","");
id+="Nodes";
var objDivId=document.getElementById(id);//element.getElementsByTagName("input");
var childrenTags= WebForm_GetElementsByTagName(objDivId,"input");
if(childrenTags!=null)
{
for(i=0;i<childrenTags.length;i++)
{
childrenTags[i].checked=element.checked;
}
}
}
}
{
var element = window.event.srcElement;
if(element.tagName=="INPUT")
{
var id=element.id.toLowerCase().replace("checkbox","");
id+="Nodes";
var objDivId=document.getElementById(id);//element.getElementsByTagName("input");
var childrenTags= WebForm_GetElementsByTagName(objDivId,"input");
if(childrenTags!=null)
{
for(i=0;i<childrenTags.length;i++)
{
childrenTags[i].checked=element.checked;
}
}
}
}
就像上文所说的,所有节点的子节点都包含在一个div中,该div的名字和父节点<table>中的名字是前部分相同,只是后部分不同,一个是checkbox一个是nodes,大家可以跟代码看一下。然后找到div之后,就可以用WebForm_GetElementsByTagName,找到所有的子孩子,然后就控制他的选择状态就可以了。WebForm_GetElementsByTagName是微软提供的函数,是根据标签从当前元素下找elements
本文转自lidup 51CTO博客,原文链接:http://blog.51cto.com/lidup/136817,如需转载请自行联系原作者