[原創]FineUI秘密花園(二十四) — 樹控件之數據綁定


上一篇文章我們介紹了樹控件的基本用法,不過都是通過標簽來聲明樹控件的結構,本章我們會詳細講解如何在后台綁定樹控件。

 

綁定到XmlDocument

下面通過一個簡單的例子來看如何將XmlDocument和樹控件綁定,頁面的標簽結構:

   1:  <ext:Tree ID="Tree1" Width="500px" EnableArrows="false" EnableLines="false" ShowHeader="true"
   2:      Title="樹控件(綁定到 XmlDocument)" runat="server">
   3:  </ext:Tree>

這里有兩個屬性需要注意:

  • EnableArrows:是夠啟用箭頭折疊標示,否則是默認的加減折疊標示。
  • EnableLines:是否啟用折疊標示之間的連接虛線。

 

來看下后台的初始化代碼:

   1:  private void LoadData()
   2:  {
   3:      string xmlPath = Server.MapPath("~/tree/databind/website.xml");
   4:   
   5:      string xmlContent = String.Empty;
   6:      using (StreamReader sr = new StreamReader(xmlPath))
   7:      {
   8:          xmlContent = sr.ReadToEnd();
   9:      }
  10:   
  11:      XmlDocument xdoc = new XmlDocument();
  12:      xdoc.LoadXml(xmlContent);
  13:   
  14:      Tree1.DataSource = xdoc;
  15:      Tree1.DataBind();
  16:  }

這段代碼的邏輯很簡單:

  1. 獲得需要讀取XML文件的服務器路徑;
  2. 使用StreamReader來讀取文件的內容;
  3. 創建XmlDocument實例,並加載XML文件內容;
  4. 設置樹控件的DataSource為此實例,並調用DataBind執行數據綁定。

 

最后來看下XML文件的內容和最終的效果截圖:

   1:  <?xml version="1.0" encoding="utf-8" ?>
   2:  <Tree>
   3:      <TreeNode Text="中國" Expanded="true" NodeId="China">
   4:          <TreeNode Text="河南省" Expanded="true" NodeId="henan">
   5:              <TreeNode Text="駐馬店市"  NodeId="zhumadian"  />
   6:              <TreeNode Text="漯河市" NodeId="luohe"  />
   7:          </TreeNode>
   8:          // 省略其他節點...
   9:      </TreeNode>
  10:  </Tree>

image

 

綁定到XmlDataSource

綁定到XmlDataSource簡化了上面的步驟,我們來看一下實現相同功能的示例:

   1:  <ext:Tree ID="Tree1" Width="500px" EnableArrows="true" EnableSingleExpand="true"
   2:      ShowHeader="true" Title="樹控件(綁定到 XmlDataSource)" runat="server">
   3:  </ext:Tree>
   4:  <asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/tree/databind/website.xml">
   5:  </asp:XmlDataSource>

 

在來看下后台初始化代碼和顯示效果:

   1:  private void LoadData()
   2:  {
   3:      Tree1.DataSource = XmlDataSource1;
   4:      Tree1.DataBind();
   5:  }

 

image

注意:在ASPX中設置了樹控件的EnableSingleExpand屬性,也就是說同一級目錄只能展開一個節點。

 

綁定到SiteMap

不知道你有沒有注意到,上面兩個例子XML文件中定義的節點屬性和樹節點的屬性一模一樣,如果不一樣怎么辦?

 

沒關系,可以為樹控件指定映射關系,用來將XML中定義的節點屬性名稱和樹節點的屬性進行對應,SiteMap就是一個典型例子。

來看一下SiteMap文件:

   1:  <?xml version="1.0" encoding="utf-8" ?>
   2:  <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
   3:    <siteMapNode title="中國" Expanded="true" NodeId="China">
   4:      <siteMapNode title="河南省" description="河南省省會" Expanded="true" NodeId="henan">
   5:        <siteMapNode title="駐馬店市" NodeId="zhumadian"  />
   6:        <siteMapNode title="漯河市" NodeId="luohe"  />
   7:      </siteMapNode>
   8:      // 省略其他節點...
   9:    </siteMapNode>
  10:  </siteMap>

其中title, description, url是SiteMap節點標准的屬性名稱,下面我們看下ASPX標簽的定義,看看如何將這些屬性名映射到樹節點的屬性:

   1:  <ext:Tree ID="Tree1" Width="500px" ShowHeader="true" Title="樹控件(綁定到 SiteMap)" runat="server">
   2:      <Mappings>
   3:          <ext:XmlAttributeMapping From="url" To="NavigateUrl" />
   4:          <ext:XmlAttributeMapping From="title" To="Text" />
   5:          <ext:XmlAttributeMapping From="description" To="ToolTip" />
   6:      </Mappings>
   7:  </ext:Tree>
   8:  <asp:XmlDataSource ID="XmlDataSource2" runat="server" DataFile="~/tree/databind/Web.sitemap">
   9:  </asp:XmlDataSource>

 

看下最終的顯示效果,特別注意“河南省”節點的Tooltip:

image

 

綁定到DataTable

在實際項目中,我們可能需要從一個數據表中讀出具有層次結構的數據,比如菜單表中通過ID和ParentID來定義這種結構。

 

下面我們通過一段代碼來生成類似的DataTable結構:

   1:  private DataTable CreateDataTable()
   2:  {
   3:      DataTable table = new DataTable();
   4:      DataColumn column1 = new DataColumn("Id", typeof(string));
   5:      DataColumn column2 = new DataColumn("Text", typeof(String));
   6:      DataColumn column3 = new DataColumn("ParentId", typeof(string));
   7:      table.Columns.Add(column1);
   8:      table.Columns.Add(column2);
   9:      table.Columns.Add(column3);
  10:   
  11:      DataRow row = table.NewRow();
  12:      row[0] = "china";
  13:      row[1] = "中國";
  14:      row[2] = DBNull.Value;
  15:      table.Rows.Add(row);
  16:   
  17:      row = table.NewRow();
  18:      row[0] = "henan";
  19:      row[1] = "河南省";
  20:      row[2] = "china";
  21:      table.Rows.Add(row);
  22:   
  23:      row = table.NewRow();
  24:      row[0] = "zhumadian";
  25:      row[1] = "駐馬店市";
  26:      row[2] = "henan";
  27:      table.Rows.Add(row);
  28:   
  29:      row = table.NewRow();
  30:      row[0] = "luohe";
  31:      row[1] = "漯河市";
  32:      row[2] = "henan";
  33:      table.Rows.Add(row);
  34:   
  35:      // 省略其他節點...
  36:   
  37:      return table;
  38:  }

毫無疑問,這段代碼生成的層次結構如下所示:

image

當然,這也是我們最終要實現的效果,來看下樹控件的初始化代碼:

   1:  protected void Page_Load(object sender, EventArgs e)
   2:  {
   3:      if (!IsPostBack)
   4:      {
   5:          LoadData();
   6:      }
   7:  }
   8:   
   9:  private void LoadData()
  10:  {
  11:      DataTable table = CreateDataTable();
  12:   
  13:      DataSet ds = new DataSet();
  14:      ds.Tables.Add(table);
  15:      ds.Relations.Add("TreeRelation", ds.Tables[0].Columns["Id"], ds.Tables[0].Columns["ParentId"]);
  16:   
  17:      foreach (DataRow row in ds.Tables[0].Rows)
  18:      {
  19:          if (row.IsNull("ParentId"))
  20:          {
  21:              TreeNode node = new TreeNode();
  22:              node.Text = row["Text"].ToString();
  23:              node.Expanded = true;
  24:              Tree1.Nodes.Add(node);
  25:   
  26:              ResolveSubTree(row, node);
  27:          }
  28:      }
  29:  }
  30:   
  31:  private void ResolveSubTree(DataRow dataRow, TreeNode treeNode)
  32:  {
  33:      DataRow[] rows = dataRow.GetChildRows("TreeRelation");
  34:      if (rows.Length > 0)
  35:      {
  36:          treeNode.Expanded = true;
  37:          foreach (DataRow row in rows)
  38:          {
  39:              TreeNode node = new TreeNode();
  40:              node.Text = row["Text"].ToString();
  41:              treeNode.Nodes.Add(node);
  42:   
  43:              ResolveSubTree(row, node);
  44:          }
  45:      }
  46:  }

這段代碼有點復雜,我們逐步來分析:

  1. 通過CreateDataTable函數拿到需要的數據源;
  2. 創建一個DataSet數據集,並把剛拿到的數據表加入此數據集,通過還定義了數據之間的聯系(ds.Relations.Add);
  3. 遍歷數據表中的每一行,找到沒有定義ParentId的行,也即是樹的根節點;
  4. 將這些根節點添加到樹控件中(Tree1.Nodes.Add);
  5. 遞歸這些根節點,並通過數據集中數據之間的關系,找到這些根節點的所有子節點,並添加到樹中。

 

小結

本章我們講解了如何將各種數據源綁定到樹控件,特別是將表格數據綁定到樹控件的做法非常耐人尋味,不過實際項目中最常用的還是將XML文件綁定到樹控件。

下一篇文章我們會講解手風琴控件,並將使用手風琴控件和樹控件組合來創建站點的菜單導航目錄。

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM