VS2005 TreeView的checkBox的父子節點級聯狀态
現在正在做一個小項目,用的是vs2005,要用到TreeView來管理一些分級資料,并能允許同時選中多個節點,是以需要用到TreeView的ShowCheckBox屬性,當我用到的時候才發現,在選中複選框時并不會引起回發事件,這時我就犯愁了,該怎麼辦呢,從網上查了好多資料,發現有不少是用javascript來實作的TreeView的父子節點級聯狀态的,但是這些方法都不太适合VS2005的TreeView,于是我繼續查閱,發現了一個比較适合VS2005的方法,下面這段話就是從一篇文章(作者是veryhappy(wx.net))裡摘錄過來的:
【大家會在ASP.NET 2 .0使用TreeView控件時發現帶有CheckBox控件的TreeNode對象(TreeView節點),選擇CheckBox無法回發頁面。在MSDN中對于TreeView.TreeNodeCheckChanged事件有一段備注:“當 TreeView 控件的複選框在兩次向伺服器發送之間更改狀态時,會引發 TreeNodeCheckChanged 事件。這使您可以提供一個這樣的事件處理方法,即每次發生此事件時執行一個自定義例程(如更新資料庫或顯示的内容)。盡管 TreeNodeCheckChanged 事件在回發時激發,但更改複選框不會導緻回發。”說明架構本身并不能提供一個CheckBox回發的機制,為了實作集聯的選擇,筆者實作了一種使用JavaScript去回發的方法,變相的解決了這個問題,盡管這樣的方法看上去很不美,但是一定程度上能解決我們的實際問題。
大緻思路,TreeNode對象輸出的是一個附和的HTML對象(包括TD,A,InputCheckBox……),本身沒有辦法增加用戶端腳本,是以為TreeView控件用戶端的onclick事件中加入腳本,腳本目的:對于引發事件的對象都做判斷,如果是InputCheckBox對象導緻的事件,則直接調用__doPostBack來回發頁面。】
下面就是代碼,我做一些擴充,可以實作點選某一個複選框時,設定它的父節點的狀态(如果它的父節點的所有子節點都沒選中,那麼父節點被設定為不選中,否則設定為選中),設定它的所有子節點的狀态為它現在的選中狀态
.aspx檔案中加一段JavaScript:
< script type = " text/javascript " >
// 點選複選框時觸發事件
function postBackByObject()
... {
var o = window.event.srcElement;
if (o.tagName == "INPUT" && o.type == "checkbox")
...{
__doPostBack("","");
}
}
</ script >
.cs檔案
級聯父子節點的複選框狀态 #region 級聯父子節點的複選框狀态
/// <summary>
/// 節點選中狀态更改
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void TreeNodeCheckChanged ( object sender, TreeNodeEventArgs e )
...{
SetChildChecked ( e.Node );
// 判斷是否是根節點
if ( !e.Node.Value.Equals ( "0" ) )
...{
SetParentChecked ( e.Node );
}
}
/// <summary>
/// 根據父節點狀态設定子節點的狀态
/// </summary>
/// <param name="parentNode"></param>
private void SetChildChecked ( TreeNode parentNode )
...{
foreach ( TreeNode node in parentNode.ChildNodes )
...{
node.Checked = parentNode.Checked;
if ( node.ChildNodes.Count > 0 )
...{
SetChildChecked ( node );
}
}
}
/// <summary>
/// 根據子節點狀态設定父節點的狀态
/// </summary>
/// <param name="childNode"></param>
private void SetParentChecked ( TreeNode childNode )
...{
TreeNode parentNode = childNode.Parent;
if ( !parentNode.Checked && childNode.Checked )
...{
parentNode.Checked=true;
}
else if(parentNode.Checked && !childNode.Checked)
...{
int checks = 0;
foreach ( TreeNode node in parentNode.ChildNodes )
...{
if ( node.Checked )
...{
checks++;
break;
}
}
if ( checks == 0 )
...{
parentNode.Checked = false;
if ( !parentNode.Value.Equals ( "0" ) )
...{
SetParentChecked ( parentNode );
}
}
}
}
#endregion