邪恶八进制信息安全团队技术讨论组's Archiver

无双坏坏 2005-8-9 09:39

[转载]ASP.Net 2.0 TreeView只能用XML資料的解決之道

文章作者:怪头
文章来源:[url]http://coolfire.fetag.org/[/url]   

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

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

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

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

PLAIN TEXTC#:

public class XmlTreeModel {

   #region Private Variable
   private int _indexid;
   private int _parentid;
   private string _title = string.Empty;
   private System.Collections.Generic.List<xmltreemodel> _childnodes = new System.Collections.Generic.List</xmltreemodel><xmltreemodel>();
   private XmlTreeModel _parent = null;
   private string _pathoftreeindex = string.Empty;
   private string _pathoftitle = string.Empty;
   private string _xmltag = string.Empty;
   private string _pathseparator = "/";  // 搭配TreeView.PathSeparator使用
   #endregion

   #region public enum XmlTreeModelPathType {...}
   public enum XmlTreeModelPathType {
      PathOfTreeIndex = 0,
      PathOfTitle = 1
   }
   #endregion

   #region Public Property
   public int IndexID { get { return _indexid; } }
   public int ParentID { get { return _parentid; } }
   public string Title { get { return _title; } }
   public System.Collections.Generic.List</xmltreemodel><xmltreemodel> ChildNodes { get { return _childnodes; } }
   public XmlTreeModel Parent { get { return _parent; } }
   public string XmlTagName { get { return _xmltag; } }
   public string PathSeparator {
      get { return _pathseparator; }
      set { _pathseparator = value; }
   }
   #endregion

   #region 多型 public XmlTreeModel()

   #region public XmlTreeModel(int indexid, string title) {...}
   public XmlTreeModel(int indexid, string title) {
      _indexid = indexid;
      _title = title;
      _pathoftitle = title;
      _pathoftreeindex = indexid.ToString();
      _xmltag = _title.Replace(&#39; &#39;, &#39;_&#39;);
   }
   #endregion

   #region public XmlTreeModel(int indexid, string title, string xmltagname) {...}
   public XmlTreeModel(int indexid, string title, string xmltagname) {
      _indexid = indexid;
      _title = title;
      _pathoftitle = title;
      _pathoftreeindex = indexid.ToString();
      _xmltag = xmltagname;
   }
   #endregion
   
   #endregion

   #region public XmlTreeModel AppendChild(XmlTreeModel item) {...}
   public XmlTreeModel AppendChild(XmlTreeModel item) {
      item._parent = this;
      item._parentid = this._indexid;
      item._pathseparator = this._pathseparator;
      item._pathoftreeindex = this._pathoftreeindex + this._pathseparator + item._pathoftreeindex;
      item._pathoftitle = this._pathoftitle + this._pathseparator + item._pathoftitle;
      _childnodes.Add(item);
      return item;
   }
   #endregion

   #region 多型 public string ToXMLString()

   #region public string ToXMLString() {...}
   public string ToXMLString() {
      return ToXMLString(false);
   }
   #endregion

   #region public string ToXMLString(bool bInsCrLf) {...}
   public string ToXMLString(bool bInsCrLf) {
      string cr = (bInsCrLf) ? "\n" : "";
      string sXml = "< " + this._xmltag + " IndexID=\"" + this._indexid + "\" Title=\"" + this._title + "\"";
      if (this._childnodes.Count == 0) {
        sXml += " />" + cr;
      } else {
        sXml += ">" + cr;
        foreach (XmlTreeModel xtm in this._childnodes) {
           string nXml = xtm.ToXMLString(bInsCrLf);
           sXml += nXml;
        }
        sXml += "" + cr;
      }
      return sXml;
   }
   #endregion

   #endregion

   #region public XmlTreeModel SearchNode(string treePath, XmlTreeModelPathType pt) {...}
   public XmlTreeModel SearchNode(string treePath, XmlTreeModelPathType pt) {
      string chkPath = string.Empty;
      switch (pt) {
        case XmlTreeModelPathType.PathOfTreeIndex:
           chkPath = this._pathoftreeindex;
           break;
        case XmlTreeModelPathType.PathOfTitle:
           chkPath=this._pathoftitle;
           break;
        default:
           break;
      }
      if (chkPath == treePath)
        return this;
      foreach (XmlTreeModel xtm in _childnodes) {
        XmlTreeModel node = xtm.SearchNode(treePath, pt);
        if (node != null)
           return node;
      }
      return null;
   }
   #endregion

}
在寫一個讀取資料庫的Class

PLAIN TEXTC#:

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

public class QAManager {

   XmlTreeModel Root;

   public string XmlString { get { return Root.ToXMLString(); } }

   public QAManager() { SetXmlTreeModel(); }

   #region private void SetXmlTreeModel() {...}
   private void SetXmlTreeModel() {
      SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
      cn.Open();
      SqlCommand cmd = new SqlCommand();
      cmd.Connection = cn;
      cmd.CommandType = CommandType.Text;
      cmd.CommandText = "Select * From TB_QAClasses Order By DataPath";
      SqlDataReader reader = cmd.ExecuteReader();
      Root = new XmlTreeModel(0, "Q & A", "Root");
      while (reader.Read()) {
        string path = (string)reader["DataPath"];
        string parentPath = path.Substring(0, path.LastIndexOf(&#39;/&#39;));
        XmlTreeModel xtm = Root.SearchNode(parentPath, XmlTreeModel.XmlTreeModelPathType.PathOfTreeIndex);
        if (xtm != null) {
           xtm.AppendChild(new XmlTreeModel((int)reader["ClassID"], (string)reader["Title"], "Class"));
        }
      }
      reader.Close();
      cmd.Dispose();
      cn.Close();
      cn.Dispose();
   }
   #endregion
}
備註一點:我所展現的樹狀路徑是記錄在資料庫中,而不是用計算的,因為每次都要計算,太累而且會影響Server loading
我的Table Schema如下:

PLAIN TEXTSQL:

CREATE TABLE [dbo].[TB_QAClasses] (
   [ClassID] [int] IDENTITY (1, 1) NOT NULL ,
   [Title] [nvarchar] (32) NOT NULL ,
   [DataPath] [varchar] (256) NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[TB_QAClasses] ADD
   CONSTRAINT [DF_TB_QAClasses_ParentID] DEFAULT (&#39;0&#39;) FOR [DataPath],
   CONSTRAINT [PK_TB_QAClasses] PRIMARY KEY  CLUSTERED
   (
      [ClassID]
   )  ON [PRIMARY]
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. 將以下程式段加入你的程式碼網頁中

PLAIN TEXTC#:

protected void Page_Load(object sender, EventArgs e) {
   if (!IsPostBack) {
      SetTreeView();
   }
}
private void SetTreeView() {
   xds.Data = new QAManager().XmlString;     // 利用QAManager自資料庫中取回資料並轉成XML格式
   xds.GetXmlDocument().LoadXml(xds.Data);    // 利用XmlDataSource的GetXmlDocument()載入XML資料
   tv.DataBindings.Clear();
   TreeNodeBinding tnb = new TreeNodeBinding();// 設定TreeView的節點
   tnb.TextField = "Title";              //
   tnb.ValueField = "IndexID";            //
   tnb.ToolTipField = "Title";            //
   tv.DataBindings.Add(tnb);             //
   tv.DataSourceID = "xds";              // 指定TreeView的DataSourceID為xds
   tv.DataBind();                    // 執行Databind()
   tv.ExpandAll();                    // 展開樹狀目錄
}
好了~ 執行看看吧... 利用以上方法,我想... 利用TreeView來展現資料庫裡的樹狀資料再也不是件難事了... ^^

页: [1]
© 1999-2008 EvilOctal Security Team