作者: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來回傳頁面。至於後台代碼就思路就簡單了,遞迴選擇相關節點,設定其Checked屬性就好了。
下面的執行個體實現了,集聯選擇當前選中節點的所有子節點功能。
代碼部分:
檔案TreeView.aspx
JavaScript:
<script>
function postBackByObject()
{
var o = window.event.srcElement;
if (o.tagName == "INPUT" && o.type == "checkbox")
{
__doPostBack("","");
}
}
</script>
Cs:
protected void Page_Load(object sender, EventArgs e)
{
TreeView1.Attributes.Add( "onclick", " postBackByObject()" );
}
protected void TreeView1_TreeNodeCheckChanged ( object sender, TreeNodeEventArgs e )
{
SetChildChecked ( e.Node );
}
private void SetChildChecked ( TreeNode p_Node )
{
foreach ( TreeNode _n in p_Node.ChildNodes )
{
_n.Checked = p_Node.Checked;
if ( _n.ChildNodes.Count > 0 )
{
SetChildChecked( _n );
}
}
}
希望還有更好的方法來解決,尤其是不用回傳頁面的方式。