天天看點

[原創]FineUI秘密花園(二十三) — 樹控件概述

樹控件用來展示具有層次結構的資料。前面在介紹下拉清單和表格控件時,我們已經接觸到模拟樹的下拉清單和模拟樹的表格,今天我們就來講解真正的樹控件。

标簽建立的樹控件

我們可以直接在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>      

顯示效果如下圖所示:

[原創]FineUI秘密花園(二十三) — 樹控件概述

由此可見,一棵樹是由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>      

這裡有幾個關鍵點:

  1. 為樹控件注冊節點指令處理函數;
  2. 在需要點選回發的樹節點上啟用EnablePostBack;
  3. 還可以指定CommandName或者CommandArgument(本例中未用到)。

來看下背景處理函數:

1:  protected void Tree1_NodeCommand(object sender, FineUI.TreeCommandEventArgs e)      
2:  {      
3:      labResult.Text = "你點選了樹節點:" + e.Node.Text;      
4:  }      

運作截圖:

[原創]FineUI秘密花園(二十三) — 樹控件概述

帶複選框的樹節點

帶複選框的樹節點隻需要啟用EnableCheckBox即可,下面的例子我們會更進一步,使用自動回發的複選框樹節點來全選/反選所有的子節點,運作效果如下圖所示:

[原創]FineUI秘密花園(二十三) — 樹控件概述

當選中河南省前面的複選框時,會回發頁面并選中河南省下面所有子節點的複選框,這是怎麼做到的呢?

先看一下頁面标簽:

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>      

這裡有幾個關鍵點:

  1. 為樹控件注冊節點選中處理函數;
  2. 在需要顯示複選框的節點上啟用EnableCheckBox;
  3. 在需要自動回發複選框的樹節點上啟用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>      

這裡有幾個關鍵點:

  1. 為樹控件注冊節點展開處理函數;
  2. 為樹控件設定AutoLeafIdentification=false;
  3. 為真正的子節點設定Leaf=true;
  4. 需要延遲加載的樹節點不要設定Leaf屬性(即預設為false)。

先來看下頁面第一次打開的截圖:

[原創]FineUI秘密花園(二十三) — 樹控件概述

此時“駐馬店市”下面并沒有子節點,是以展開此節點時會觸發樹控件的節點展開事件。

下面來看下節點展開事件的處理函數:

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秘密花園(二十三) — 樹控件概述

注:第一次展開“駐馬店市”之後,就向其中添加了子節點,是以折疊後再次展開此節點就不會觸發節點展開事件了。

小結

本章我們介紹了樹控件的各種用法,樹節點不僅可以被渲染為普通文本、超連結、可回發的文本,而且可以渲染為帶自動回發複選框的文本,同時我們還講解了延遲樹節點的用法。

下一篇文章我們會介紹如何将各種不同的資料源綁定到将樹控件。

注:《FineUI秘密花園》系列文章由三生石上原創,部落格園首發,轉載請注明出處。文章目錄 官方論壇