解決TreeView 遇到大量資料時效能很差

解決TreeView 遇到大量資料時效能很差

 

問題:

TreeView如果遇到資料破千筆時效能會變得很差,再加上每次點選節點就重整一次,使用起來會覺得好像一直在等待

 

解法:

在這裡我選擇的方法是一開始只讀取父階層,當使用者展開樹再去讀取相對應子節點

 

KeyPoint:

  1. 父階層與子階層要分開讀取
  2. TreeView展開事件TreeNodePopulate
  3. TreeNode要把PopulateOnDemand = True
  4. 善用TreeNode的屬性

 

.aspx:

畫面很簡單就只有一個TreeView

  • 預設要展開的階層數 ExpandDepth="0" 
  • Tree展開的事件 OnTreeNodePopulate="TreeView1_TreeNodePopulate"

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TreeView ID="TreeView1" runat="server" ExpandDepth="0" OnTreeNodePopulate="TreeView1_TreeNodePopulate">

        </asp:TreeView>
    </div>
    </form>
</body>
</html>

 

Code:

初始化TreeView

要將父階層(清單)與子階層(明細)分開讀取

 


protected void Page_Load(object sender, EventArgs e)
{
    if (this.IsPostBack)
        return;

    //加入清單
    RetriveRoot();
}


#region 資料繫結
private void RetriveRoot()
{
    TreeView1.Nodes.Clear();
    DalEmployees Dal=new DalEmployees();
    DataTable RootData;

    RootData = Dal.GetDataTable("SELECT * FROM Employees");
    foreach (DataRow dr in RootData.Rows)
    {
        //加入清單
        string TreeNodeText = String.Format("姓名:{0} {1},生日:{2},電話:{3}", dr["LastName"].ToString(), dr["FirstName"].ToString(), dr["BirthDate"].ToString(), dr["HomePhone"].ToString());
        //PK 如果有多個索引值可以用,分開 之後再使用String.Split(',')做擷取
        string TreeNodeValue = dr["EmployeeID"].ToString();
        TreeNode tn = new TreeNode(TreeNodeText, TreeNodeValue);

        TreeView1.Nodes.Add(tn);
        //允許載入節點
        tn.PopulateOnDemand = true;
    }
}


private void RetriveSub(TreeNode parentNode)
{
    DalEmployees Dal = new DalEmployees();
    DataTable SubData;
    string CmdText = string.Format("SELECT * FROM Orders WHERE EmployeeID='{0}'", parentNode.Value);

    SubData = Dal.GetDataTable(CmdText);
    foreach (DataRow dr in SubData.Rows)
    {
        //加入明細
        TreeNode tn = new TreeNode(
             String.Format("客戶名稱:{0},訂單日期:{1}", dr["CustomerID"].ToString(), dr["OrderDate"].ToString())
            , dr["OrderID"].ToString());

        parentNode.ChildNodes.Add(tn);
    }
}
#endregion


protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e)
{
    //加入明細
    RetriveSub(e.Node);
}

資料存取 DataAccess:

 


/// <summary>
/// 取得資料
/// </summary>
/// <param name="CmdText">資料來源T-SQL</param>
/// <returns></returns>
public DataTable GetDataTable(string CmdText)
{
    string ConnStr;
    SqlConnection Conn;
    SqlDataAdapter Da;
    DataSet Ds;

    //設定連接字串,這裡用Northwind北風資料庫當範例,連接字串請自行修改
    ConnStr = "Data Source=(local);Persist Security Info=True;database=Northwind;User ID=jshsshwa;Password=123";
    //建立Connection
    using (Conn = new SqlConnection(ConnStr))
    {
        Conn.Open();

        //建立DataAdapter並且取得資料
        Da = new SqlDataAdapter(CmdText,Conn);
        //建立DataSet
        Ds = new DataSet();
        //資料填入DataSet
        Da.Fill(Ds);

        return Ds.Tables[0]; ;
    }

}