传统的树形控件都是程序员主动向结点附加子结点的,也就是说,如果你想添加一个结点,你必须先知道他的父亲!然后给他添加儿子、孙子等等。
只有懒人才会创新,因为他总想偷懒,总想着如何省事!
现在,我写的这个树形控件非常简单,您只要把一个具有树形结构的datatable给他,他就会自动为你做好一切,他的用法只比dropdownlist多设置一个值:
DataSet ds = ...;
DataTable table = ds.Tables[0];
TreeView_Xiehuiqi1.DataSource = table;
TreeView_Xiehuiqi1.DataValueField = "ID";
TreeView_Xiehuiqi1.DataTextField = "Name";
TreeView_Xiehuiqi1.DataParentField = "ParentID";
TreeView_Xiehuiqi1.BindData();
然后这棵树就自动生成了,效果如下:
当您改变节点的顺序时,他也不会出错,比如把数据排序方式改变,效果如下:
现在来看看他的核心代码:
其实在我们虽然是赋给了一个table给他,但是在客户端他将生成如下具有json格式的数组:
var nodeList=
[
{id:"633507872779375000169",text:"打击乐器2",parent:"633507864237968750148"},
{id:"633507864237968750148",text:"打击乐器1",parent:"633477364828750000004"},
{id:"633506823853906250110",text:"立式钢琴",parent:"633506823686875000109"},
{id:"633506823686875000109",text:"豪富曼钢琴",parent:"633477364828750000001"},
{id:"633506823340781250108",text:"立式钢琴",parent:"633506822696562500106"},
{id:"633506823167031250107",text:"三角钢琴",parent:"633506822696562500106"},
{id:"633506822696562500106",text:"Petrof钢琴",parent:"633477364828750000001"},
{id:"633506819402031250105",text:"立式钢琴",parent:"633487954946093750102"},
{id:"633506818545000000104",text:"立式钢琴",parent:"633506818089843750101"},
{id:"633506818332656250103",text:"三角钢琴",parent:"633506818089843750101"},
{id:"633506818089843750101",text:"雅马哈钢琴",parent:"633477364828750000001"},
{id:"633500759003906250108",text:"立式钢琴",parent:"633487954946093750101"},
{id:"633500729685000000101",text:"立式钢琴",parent:"633492242363593750101"},
{id:"633499817566035000102",text:"立式钢琴",parent:"633487944947812500101"},
{id:"633495722735316250152",text:"管乐2",parent:"633495713687503750140"},
{id:"633495713687503750140",text:"管乐1",parent:"633477364828750000002"},
{id:"633492268602656250114",text:"三角钢琴",parent:"633492242363593750101"},
{id:"633492268519062500113",text:"三角钢琴",parent:"633487954946093750102"},
{id:"633492268427968750112",text:"三角钢琴",parent:"633487954946093750101"},
{id:"633492242363593750101",text:"郎朗钢琴",parent:"633477364828750000001"},
{id:"633487954946093750102",text:"施坦威钢琴",parent:"633477364828750000001"},
{id:"633487954946093750101",text:"艾塞克斯钢琴",parent:"633477364828750000001"},
{id:"633487948397187500101",text:"三角钢琴",parent:"633487944947812500101"},
{id:"633487944947812500101",text:"波士顿钢琴",parent:"633477364828750000001"},
{id:"633477364828750000007",text:"其他产品",parent:"0"},
{id:"633477364828750000006",text:"专业音响",parent:"0"},
{id:"633477364828750000005",text:"MIDI",parent:"0"},
{id:"633477364828750000004",text:"打击乐器",parent:"0"},
{id:"633477364828750000003",text:"吉他与音箱",parent:"0"},
{id:"633477364828750000002",text:"管乐",parent:"0"},
{id:"633477364828750000001",text:"钢琴与键盘",parent:"0"},
]
然后通过bind函数把该数组生成html节点:
function bind(nodes)
{
var nodeLength=nodes.length;
for(var i=0;i<nodeLength-1;i++)
{
var data=nodes[i];
var dataItem=document.createElement("div");
var parentID = data.parent;
dataItem.innerHTML = _propTextPrefix + data.text;
dataItem.id = data.id;
dataItem.parent = parentID;
dataItem.className="div_treeview_xiehuiqi";
var parentItem=document.getElementById(parentID);
//第一,如果找到了该节点的父亲节点
//在其父亲节点下插入该节点
if (parentItem)
{
appendChild(dataItem, parentItem);
}
else
{
appendChild(dataItem,root);
}
//第二,把其所有的儿子节点插入到当前节点下
appendAllChild(dataItem);
}
}
不过这个控件现在并没有实现点击以及链接效果,但是既然核心代码实现了,那些又算什么呢?
所有的客户端代码如下,很很简洁,大家自己看注释吧,若有疑问请留言或email!
----------------------------------------------------------------------------------------------------
var _propTextPrefix = "├";
var root=document.getElementById("cPanel");
var stack=[];//附加节点缓冲区
function bind(nodes)
{
var nodeLength=nodes.length;
for(var i=0;i<nodeLength-1;i++)
{
var data=nodes[i];
var dataItem=document.createElement("div");
var parentID = data.parent;
dataItem.innerHTML = _propTextPrefix + data.text;
dataItem.id = data.id;
dataItem.parent = parentID;
dataItem.className="div_treeview_xiehuiqi";
var parentItem=document.getElementById(parentID);
//第一,如果找到了该节点的父亲节点
//在其父亲节点下插入该节点
if (parentItem)
{
appendChild(dataItem, parentItem);
}
else
{
appendChild(dataItem,root);
}
//第二,把其所有的儿子节点插入到当前节点下
appendAllChild(dataItem);
}
}
function appendChild(child,parentNode)
{
parentNode.appendChild(child);
}
function appendAllChild(parentNode)
{
var n=root.getElementsByTagName("*");
for(var j=0;j<n.length;j++)
{
if(n[j].getAttribute("parent")==parentNode.id)
{
stack.push({child:n[j],parent:parentNode});
}
}
for(var k in stack)
{
appendChild(stack[k].child,stack[k].parent);
}
}
bind(nodeList);