樹控件用來展示具有層次結構的數據。前面在介紹下拉列表和表格控件時,我們已經接觸到模擬樹的下拉列表和模擬樹的表格,今天我們就來講解真正的樹控件。
標簽創建的樹控件
我們可以直接在ASPX頁面中創建樹控件,非常直觀,比如:
1: <ext:Tree ID="Tree1" Width="500px" ShowHeader="true" Title="樹控件(內聯)" runat="server">
2: <Nodes>
3: <ext:TreeNode Text="中國" Expanded="true">
4: <ext:TreeNode Text="河南省" Expanded="true">
5: <ext:TreeNode Text="駐馬店市" NodeID="zhumadian">
6: <ext:TreeNode Text="遂平縣" Leaf="false" NodeID="suiping">
7: <ext:TreeNode Text="槐樹鄉" Leaf="false" NodeID="huaishu">
8: <ext:TreeNode Text="陳庄村" Leaf="true" NodeID="chenzhuang">
9: </ext:TreeNode>
10: </ext:TreeNode>
11: </ext:TreeNode>
12: </ext:TreeNode>
13: <ext:TreeNode Text="漯河市" Leaf="true" NodeID="luohe" />
14: </ext:TreeNode>
15: // 省略其他節點...
16: </ext:TreeNode>
17: </Nodes>
18: </ext:Tree>
顯示效果如下圖所示:
由此可見,一棵樹是由TreeNode節點嵌套而來的,下面就來看下TreeNode有哪些屬性:
樹節點的常用屬性
- Text:樹節點文本
- NodeID:樹節點ID
- Leaf:是否葉子節點
- Enabled:是否可用
- Expanded:是否展開
- NavigateUrl:鏈接地址
- Target:鏈接目標
- Icon:預定義圖標
- IconUrl:圖標地址
- ToolTip:提示文本
- SingleClickExpand:單擊可切換節點的折疊展開狀態
由此可見,樹節點可以禁用、可以渲染為超鏈接、可以定義圖標、可以設置提示文本。
可以回發的樹節點
- EnablePostBack:是否可以回發(單擊樹節點)
- OnClientClick:點擊按鈕時需要執行的客戶端腳本
- CommandName:命令名稱
- CommandArgument:命令參數
可見,樹節點也可以作為一個按鈕來觸發后台事件,只不過這個事件定義是在樹控件上。而CommandName和CommandArgument則類似於表格控件中LinkButtonField定義的同名屬性。
帶復選框的樹節點
- Checked:是否選中
- EnableCheckBox:是否啟用復選框
- AutoPostBack:是否自動回發(改變復選框狀態)
可見,樹節點也可以作為一個復選框來觸發后台事件。這里AutoPostBack屬性就類似於表格控件中CheckBoxField定義的同名屬性。
可以回發的樹節點
通過一個簡單示例來講解其用法:
1: <ext:Tree ID="Tree1" Width="500px" OnNodeCommand="Tree1_NodeCommand" ShowHeader="true"
2: Title="樹控件" runat="server">
3: <Nodes>
4: <ext:TreeNode Text="中國" Expanded="true">
5: <ext:TreeNode Text="河南省" Expanded="true">
6: <ext:TreeNode Text="駐馬店市(點擊回發)" EnablePostBack="true" Expanded="true" NodeID="Zhumadian">
7: <ext:TreeNode Text="遂平縣(點擊回發)" EnablePostBack="true" NodeID="Suiping">
8: </ext:TreeNode>
9: <ext:TreeNode Text="西平縣(點擊回發)" EnablePostBack="true" NodeID="Xiping">
10: </ext:TreeNode>
11: </ext:TreeNode>
12: <ext:TreeNode Text="漯河市" Enabled="true" NodeID="Luohe" />
13: </ext:TreeNode>
14: // 省略其他節點...
15: </ext:TreeNode>
16: </Nodes>
17: </ext:Tree>
這里有幾個關鍵點:
- 為樹控件注冊節點命令處理函數;
- 在需要點擊回發的樹節點上啟用EnablePostBack;
- 還可以指定CommandName或者CommandArgument(本例中未用到)。
來看下后台處理函數:
1: protected void Tree1_NodeCommand(object sender, FineUI.TreeCommandEventArgs e)
2: {
3: labResult.Text = "你點擊了樹節點:" + e.Node.Text;
4: }
運行截圖:
帶復選框的樹節點
帶復選框的樹節點只需要啟用EnableCheckBox即可,下面的例子我們會更進一步,使用自動回發的復選框樹節點來全選/反選所有的子節點,運行效果如下圖所示:
當選中河南省前面的復選框時,會回發頁面並選中河南省下面所有子節點的復選框,這是怎么做到的呢?
先看一下頁面標簽:
1: <ext:Tree ID="Tree1" OnNodeCheck="Tree1_NodeCheck" Width="500px" ShowHeader="true"
2: Title="樹控件" runat="server">
3: <Nodes>
4: <ext:TreeNode Text="中國" EnableCheckBox="true" AutoPostBack="true" Expanded="true">
5: <ext:TreeNode AutoPostBack="true" Text="河南省" EnableCheckBox="true" Expanded="true">
6: <ext:TreeNode Text="駐馬店市" AutoPostBack="true" EnableCheckBox="true" NodeID="zhumadian">
7: <ext:TreeNode Text="遂平縣" AutoPostBack="true" EnableCheckBox="true" NodeID="Suiping">
8: </ext:TreeNode>
9: <ext:TreeNode Text="西平縣" AutoPostBack="true" EnableCheckBox="true" NodeID="Xiping">
10: </ext:TreeNode>
11: </ext:TreeNode>
12: <ext:TreeNode Text="漯河市" AutoPostBack="true" EnableCheckBox="true" NodeID="luohe" />
13: </ext:TreeNode>
14: // 省略其他節點...
15: </ext:TreeNode>
16: </Nodes>
17: </ext:Tree>
這里有幾個關鍵點:
- 為樹控件注冊節點選中處理函數;
- 在需要顯示復選框的節點上啟用EnableCheckBox;
- 在需要自動回發復選框的樹節點上啟用AutoPostBack;
再來看下選中節點復選框的處理函數:
1: protected void Tree1_NodeCheck(object sender, FineUI.TreeCheckEventArgs e)
2: {
3: if (e.Checked)
4: {
5: Tree1.CheckAllNodes(e.Node.Nodes);
6: }
7: else
8: {
9: Tree1.UncheckAllNodes(e.Node.Nodes);
10: }
11: }
這里調用了CheckAllNodes函數來選中所有的子節點,當然我們也可以手工遞歸所有的子節點來完成此操作。
下面是使用遞歸的方式來完成此操作的參考代碼:
1: protected void Tree1_NodeCheck(object sender, FineUI.TreeCheckEventArgs e)
2: {
3: if (!e.Node.Leaf)
4: {
5: CheckTreeNode(e.Node.Nodes, e.Checked);
6: }
7: }
8:
9: private void CheckTreeNode(TreeNodeCollection nodes, bool isChecked)
10: {
11: foreach (TreeNode node in nodes)
12: {
13: node.Checked = isChecked;
14: if (!node.Leaf)
15: {
16: CheckTreeNode(node.Nodes, isChecked);
17: }
18: }
19: }
延遲加載的樹節點
在上面這些例子中,不知道你有沒有發現一個細節,有時我們為子節點設置了Leaf=true,有時又沒有設置,不過似乎都能正常運行,這是怎么回事?
其實,是否為樹節點設置Leaf屬性都可以,因為FineUI內部會重新遞歸所有的子節點,將擁有子節點的節點Leaf屬性設為false,反之設為true。控制這一行為的屬性就是AutoLeafIdentification(默認值為true)。
如果將樹控件的AutoLeafIdentification設為false,則我們就需要為每一個子節點設置Leaf=true(默認為false),如果沒有為一個理應成為子節點的節點設置Leaf=true,則此節點就會被渲染為一個可折疊展開的父節點,展開此節點時就會觸發樹控件的NodeExpand事件。
正好,我們可以利用這一特性來完成延遲加載的樹節點,是不是很巧妙。下面通過一個示例來演示。
先看頁面的標簽:
1: <ext:Tree ID="Tree1" EnableArrows="true" OnNodeExpand="Tree1_NodeExpand" Width="500px"
2: ShowHeader="true" Title="延遲加載的樹控件" AutoLeafIdentification="false" runat="server">
3: <Nodes>
4: <ext:TreeNode Text="中國" Expanded="true">
5: <ext:TreeNode Text="河南省" Expanded="true">
6: <ext:TreeNode Text="駐馬店市(此節點延遲加載)" NodeID="zhumadian">
7: </ext:TreeNode>
8: <ext:TreeNode Text="漯河" NodeID="luohe" Leaf="true" />
9: </ext:TreeNode>
10: // 省略其他節點...
11: </ext:TreeNode>
12: </Nodes>
13: </ext:Tree>
這里有幾個關鍵點:
- 為樹控件注冊節點展開處理函數;
- 為樹控件設置AutoLeafIdentification=false;
- 為真正的子節點設置Leaf=true;
- 需要延遲加載的樹節點不要設置Leaf屬性(即默認為false)。
先來看下頁面第一次打開的截圖:
此時“駐馬店市”下面並沒有子節點,因此展開此節點時會觸發樹控件的節點展開事件。
下面來看下節點展開事件的處理函數:
1: protected void Tree1_NodeExpand(object sender, FineUI.TreeExpandEventArgs e)
2: {
3: DynamicAppendNode(e.Node);
4: }
5:
6: private void DynamicAppendNode(TreeNode parentNode)
7: {
8: parentNode.Expanded = true;
9:
10: TreeNode node = null;
11: switch (parentNode.NodeID)
12: {
13: case "zhumadian":
14: node = new TreeNode();
15: node.Text = "遂平縣";
16: node.Leaf = false;
17: node.NodeID = "suiping";
18: parentNode.Nodes.Add(node);
19:
20: node = new TreeNode();
21: node.Text = "西平縣";
22: node.Leaf = true;
23: node.NodeID = "xiping";
24: parentNode.Nodes.Add(node);
25: break;
26: case "suiping":
27: node = new TreeNode();
28: node.Text = "槐樹鄉";
29: node.Leaf = false;
30: node.NodeID = "huaishu";
31: parentNode.Nodes.Add(node);
32: break;
33: case "huaishu":
34: node = new TreeNode();
35: node.Text = "陳庄村";
36: node.Leaf = true;
37: node.NodeID = "chenzhuang";
38: parentNode.Nodes.Add(node);
39: break;
40: }
41: }
這段代碼不僅處理展開“駐馬店市”的情況,而且處理下面的層次結構,通過NodeID進行關聯,大家可以認真分析下這段代碼。
下面是運行截圖:
注:第一次展開“駐馬店市”之后,就向其中添加了子節點,所以折疊后再次展開此節點就不會觸發節點展開事件了。
小結
本章我們介紹了樹控件的各種用法,樹節點不僅可以被渲染為普通文本、超鏈接、可回發的文本,而且可以渲染為帶自動回發復選框的文本,同時我們還講解了延遲樹節點的用法。
下一篇文章我們會介紹如何將各種不同的數據源綁定到將樹控件。