樹控件用來展示具有層次結構的資料。前面在介紹下拉清單和表格控件時,我們已經接觸到模拟樹的下拉清單和模拟樹的表格,今天我們就來講解真正的樹控件。
标簽建立的樹控件
我們可以直接在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進行關聯,大家可以認真分析下這段代碼。
下面是運作截圖:
注:第一次展開“駐馬店市”之後,就向其中添加了子節點,是以折疊後再次展開此節點就不會觸發節點展開事件了。
小結
本章我們介紹了樹控件的各種用法,樹節點不僅可以被渲染為普通文本、超連結、可回發的文本,而且可以渲染為帶自動回發複選框的文本,同時我們還講解了延遲樹節點的用法。
下一篇文章我們會介紹如何将各種不同的資料源綁定到将樹控件。
注:《FineUI秘密花園》系列文章由三生石上原創,部落格園首發,轉載請注明出處。文章目錄 官方論壇