大家會在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 );
}
}
}