tangdh
PB and .net 乐园

导航

 
     

在前幾個章節所介紹的TreeView
([ASP.NET 2.0]SiteMapPath無法正確指到帶有QueryString的路徑
[ASP.NET 2.0]SiteMapPath WebControl)
有個限制(至少我覺得是限制),那就是只能使用XML的資料格式

但假如我們的資料是資料庫形式的資料該怎麼辦?

有兩個解決方法:一是自己寫程式,將節點加到TreeViewNode裡;一是另外寫個類似TreeViewNode的Class自己用
我是選第二個方法,這樣我就不用每次使用TreeView時,都要在寫那麼長一段程式碼了

先寫一個XmlTreeModel,程式碼如下:

C#:
  1. public class XmlTreeModel {
  2.  
  3.     #region Private Variable
  4.     private int _indexid;
  5.     private int _parentid;
  6.     private string _title = string.Empty;
  7.     private System.Collections.Generic.List<xmltreemodel> _childnodes = new System.Collections.Generic.List</xmltreemodel><xmltreemodel>();
  8.     private XmlTreeModel _parent = null;
  9.     private string _pathoftreeindex = string.Empty;
  10.     private string _pathoftitle = string.Empty;
  11.     private string _xmltag = string.Empty;
  12.     private string _pathseparator = "/";   // 搭配TreeView.PathSeparator使用
  13.     #endregion
  14.  
  15.     #region public enum XmlTreeModelPathType {...}
  16.     public enum XmlTreeModelPathType {
  17.         PathOfTreeIndex = 0,
  18.         PathOfTitle = 1
  19.     }
  20.     #endregion
  21.  
  22.     #region Public Property
  23.     public int IndexID { get { return _indexid; } }
  24.     public int ParentID { get { return _parentid; } }
  25.     public string Title { get { return _title; } }
  26.     public System.Collections.Generic.List</xmltreemodel><xmltreemodel> ChildNodes { get { return _childnodes; } }
  27.     public XmlTreeModel Parent { get { return _parent; } }
  28.     public string XmlTagName { get { return _xmltag; } }
  29.     public string PathSeparator {
  30.         get { return _pathseparator; }
  31.         set { _pathseparator = value; }
  32.     }
  33.     #endregion
  34.  
  35.     #region 多型 public XmlTreeModel()
  36.  
  37.     #region public XmlTreeModel(int indexid, string title) {...}
  38.     public XmlTreeModel(int indexid, string title) {
  39.         _indexid = indexid;
  40.         _title = title;
  41.         _pathoftitle = title;
  42.         _pathoftreeindex = indexid.ToString();
  43.         _xmltag = _title.Replace(' ', '_');
  44.     }
  45.     #endregion
  46.  
  47.     #region public XmlTreeModel(int indexid, string title, string xmltagname) {...}
  48.     public XmlTreeModel(int indexid, string title, string xmltagname) {
  49.         _indexid = indexid;
  50.         _title = title;
  51.         _pathoftitle = title;
  52.         _pathoftreeindex = indexid.ToString();
  53.         _xmltag = xmltagname;
  54.     }
  55.     #endregion
  56.    
  57.     #endregion
  58.  
  59.     #region public XmlTreeModel AppendChild(XmlTreeModel item) {...}
  60.     public XmlTreeModel AppendChild(XmlTreeModel item) {
  61.         item._parent = this;
  62.         item._parentid = this._indexid;
  63.         item._pathseparator = this._pathseparator;
  64.         item._pathoftreeindex = this._pathoftreeindex + this._pathseparator + item._pathoftreeindex;
  65.         item._pathoftitle = this._pathoftitle + this._pathseparator + item._pathoftitle;
  66.         _childnodes.Add(item);
  67.         return item;
  68.     }
  69.     #endregion
  70.  
  71.     #region 多型 public string ToXMLString()
  72.  
  73.     #region public string ToXMLString() {...}
  74.     public string ToXMLString() {
  75.         return ToXMLString(false);
  76.     }
  77.     #endregion
  78.  
  79.     #region public string ToXMLString(bool bInsCrLf) {...}
  80.     public string ToXMLString(bool bInsCrLf) {
  81.         string cr = (bInsCrLf) ? "\n" : "";
  82.         string sXml = "< " + this._xmltag + " IndexID=\"" + this._indexid + "\" Title=\"" + this._title + "\"";
  83.         if (this._childnodes.Count == 0) {
  84.             sXml += " />" + cr;
  85.         } else {
  86.             sXml += ">" + cr;
  87.             foreach (XmlTreeModel xtm in this._childnodes) {
  88.                 string nXml = xtm.ToXMLString(bInsCrLf);
  89.                 sXml += nXml;
  90.             }
  91.             sXml += "" + cr;
  92.         }
  93.         return sXml;
  94.     }
  95.     #endregion
  96.  
  97.     #endregion
  98.  
  99.     #region public XmlTreeModel SearchNode(string treePath, XmlTreeModelPathType pt) {...}
  100.     public XmlTreeModel SearchNode(string treePath, XmlTreeModelPathType pt) {
  101.         string chkPath = string.Empty;
  102.         switch (pt) {
  103.             case XmlTreeModelPathType.PathOfTreeIndex:
  104.                 chkPath = this._pathoftreeindex;
  105.                 break;
  106.             case XmlTreeModelPathType.PathOfTitle:
  107.                 chkPath=this._pathoftitle;
  108.                 break;
  109.             default:
  110.                 break;
  111.         }
  112.         if (chkPath == treePath)
  113.             return this;
  114.         foreach (XmlTreeModel xtm in _childnodes) {
  115.             XmlTreeModel node = xtm.SearchNode(treePath, pt);
  116.             if (node != null)
  117.                 return node;
  118.         }
  119.         return null;
  120.     }
  121.     #endregion
  122.  
  123. }

在寫一個讀取資料庫的Class

C#:
  1. using System;
  2. using System.Configuration;
  3. using System.Data;
  4. using System.Data.SqlClient;
  5.  
  6. public class QAManager {
  7.  
  8.     XmlTreeModel Root;
  9.  
  10.     public string XmlString { get { return Root.ToXMLString(); } }
  11.  
  12.     public QAManager() { SetXmlTreeModel(); }
  13.  
  14.     #region private void SetXmlTreeModel() {...}
  15.     private void SetXmlTreeModel() {
  16.         SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
  17.         cn.Open();
  18.         SqlCommand cmd = new SqlCommand();
  19.         cmd.Connection = cn;
  20.         cmd.CommandType = CommandType.Text;
  21.         cmd.CommandText = "Select * From TB_QAClasses Order By DataPath";
  22.         SqlDataReader reader = cmd.ExecuteReader();
  23.         Root = new XmlTreeModel(0, "Q &amp; A", "Root");
  24.         while (reader.Read()) {
  25.             string path = (string)reader["DataPath"];
  26.             string parentPath = path.Substring(0, path.LastIndexOf('/'));
  27.             XmlTreeModel xtm = Root.SearchNode(parentPath, XmlTreeModel.XmlTreeModelPathType.PathOfTreeIndex);
  28.             if (xtm != null) {
  29.                 xtm.AppendChild(new XmlTreeModel((int)reader["ClassID"], (string)reader["Title"], "Class"));
  30.             }
  31.         }
  32.         reader.Close();
  33.         cmd.Dispose();
  34.         cn.Close();
  35.         cn.Dispose();
  36.     }
  37.     #endregion
  38. }

備註一點:我所展現的樹狀路徑是記錄在資料庫中,而不是用計算的,因為每次都要計算,太累而且會影響Server loading
我的Table Schema如下:

SQL:
  1. CREATE TABLE [dbo].[TB_QAClasses] (
  2.     [ClassID] [int] IDENTITY (1, 1) NOT NULL ,
  3.     [Title] [nvarchar] (32) NOT NULL ,
  4.     [DataPath] [varchar] (256) NOT NULL
  5. ) ON [PRIMARY]
  6. GO
  7.  
  8. ALTER TABLE [dbo].[TB_QAClasses] ADD
  9.     CONSTRAINT [DF_TB_QAClasses_ParentID] DEFAULT ('0') FOR [DataPath],
  10.     CONSTRAINT [PK_TB_QAClasses] PRIMARY KEY  CLUSTERED
  11.     (
  12.         [ClassID]
  13.     )  ON [PRIMARY]
  14. GO

[2005/08/01 15:53補充]
資料表內容如下...

ClassID Title DataPath
1 類別一 0/1
2 類別二 0/2
3 類別一之一 0/1/3
4 類別二之一 0/2/4

準備工作已經做完了... 現在要來在網頁裡利用TreeView來展現樹狀資料了

1. 先在網頁裡新增兩個元件XmlDataSource(更名為xds)以及TreeView(更名為tv)
2. 將以下程式段加入你的程式碼網頁中

C#:
  1. protected void Page_Load(object sender, EventArgs e) {
  2.     if (!IsPostBack) {
  3.         SetTreeView();
  4.     }
  5. }
  6. private void SetTreeView() {
  7.     xds.Data = new QAManager().XmlString;       // 利用QAManager自資料庫中取回資料並轉成XML格式
  8.     xds.GetXmlDocument().LoadXml(xds.Data);     // 利用XmlDataSource的GetXmlDocument()載入XML資料
  9.     tv.DataBindings.Clear();
  10.     TreeNodeBinding tnb = new TreeNodeBinding();// 設定TreeView的節點
  11.     tnb.TextField = "Title";                    //
  12.     tnb.ValueField = "IndexID";                 //
  13.     tnb.ToolTipField = "Title";                 //
  14.     tv.DataBindings.Add(tnb);                   //
  15.     tv.DataSourceID = "xds";                    // 指定TreeView的DataSourceID為xds
  16.     tv.DataBind();                              // 執行Databind()
  17.     tv.ExpandAll();                             // 展開樹狀目錄
  18. }

好了~ 執行看看吧... 利用以上方法,我想... 利用TreeView來展現資料庫裡的樹狀資料再也不是件難事了... ^^

posted on 2006-03-25 12:18  tangdh  阅读(1537)  评论(1)    收藏  举报