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吹的很不錯,但用戶端操作幾乎為零。微軟實現了一些用戶端用的JavaScript 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/>, 無法分析(因此我自己JavaScript才會裡出現A節點和Input節點,A節點就是有“樹ID + “n” + 節點序號”為ID的連結元素,Input節點是<table/>裡的Checkbox,命名規則為: 樹ID + “n” + 節點序號 + “CheckBox”)
3 自己寫JavaScript
沒辦法,只有自己寫JS函數來處理CheckBox的級聯操作,其中用到了微軟的TreeView.js 和 WebForm.js,下載連結: TreeView2.rar
加入方法如下:
* 為TreeView加入OnClick事件
直接在TreeView的屬性上加入:OnClick="OnTreeNodeChecked()"
或者:MyTree.Attributes.Add("OnClick", "OnTreeNodeChecked(event)");
* 這樣寫OnClick事件動作
<script language =javascript type="text/javascript">
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);
}
</script>
TreeView2.js 也包含了一些對節點訪問函數,可做其他用途。隨著我自己需求的增加,我也會逐漸加入其他的一些功能進去。
Update:
有朋友問到:在用戶端如何取節點值?
整個樹的資料都作為XML放在ViewState中,節點的Value也就放在ViewState中,要分析它還有些麻煩。不過,可以看看這個工具(ViewStatueDecoder):http://www.pluralsight.com/tools.aspx,會有些啟發
Update 20060624:
針對shenghualuo實驗不通的情況,我貼一個例子: http://files.cnblogs.com/itrust/index.rar
注意:由於例子源於我一個基於MonoRail的項目,因此Save不能使用