asp.net2 无刷新动态加载树

因为树比较大(可能有几千个点),一次全部加载速度不能接受。因此方案是动态加载:开始只列出少量一层数据,然后随着使用者不断点击节点,动态载入下级节点,这样因为每次点击只载入几十个节点,速度就可以接受了。

 

 

以下代码从 msdn 复制,可通过 treeview 控件的 PopulateNodesFromClient 等属性的说明找到这段代码。如果完全复制的话,执行时的效果是一个完全展开、写进所有数据的树,这看起来根本不是想要的效果。这时只需要改一个地方:增加树的 ExpandDepth="0" 属性。想想也是,默认树完全展开,不就是开始看到的效果?

加入了 ExpandDepth="0" 后,效果是,树只有初始节点,任何需要动态加入到节点都没有。这时点开一节点(+ 号),子节点无刷新加入;下级类似。查看 html 源文件,只有初始节点的 html 码,ok,这就是想要的。

有一点注意,通过正取设置 select,然后通过按钮或其它方式选中,把选中结果发给服务器,这时服务端程序可取得选中,然后此时返回的页面是包括树的所有已经加载数据的,即同服务器往返一次后,在查看 html 源,则树中所有已加入数据都在 html 里。这样往返的成本仍然很高,不过毕竟省下了读取数据环节。

通过 .net ajax 的 updatepanel 当然避免不了这些往返成本,可以通过 子框架,使树指向框架,这样就避免了树的往返,不过页面设计就分散了。。。

 

<%@ Page Language="C#" %>

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.SqlClient" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

 

  void PopulateNode(Object sender, TreeNodeEventArgs e)

  {

    // Call the appropriate method to populate a node at a particular level.

    switch(e.Node.Depth)

    {

      case 0:

        // Populate the first-level nodes.

        PopulateCategories(e.Node);

        break;

      case 1:

        // Populate the second-level nodes.

        PopulateProducts(e.Node);

        break;

      default:

        // Do nothing.

        break;

    }

 

  }

 

  void PopulateCategories(TreeNode node)

  {

 

    // Query for the product categories. These are the values

    // for the second-level nodes.

    DataSet ResultSet = RunQuery("Select CategoryID, CategoryName From Categories");

 

    // Create the second-level nodes.

    if(ResultSet.Tables.Count > 0)

    {

 

      // Iterate through and create a new node for each row in the query results.

      // Notice that the query results are stored in the table of the DataSet.

      foreach (DataRow row in ResultSet.Tables[0].Rows)

      {

 

        // Create the new node. Notice that the CategoryId is stored in the Value property

        // of the node. This will make querying for items in a specific category easier when

        // the third-level nodes are created.

        TreeNode newNode = new TreeNode();

        newNode.Text = row["CategoryName"].ToString();

        newNode.Value = row["CategoryID"].ToString();       

 

        // Set the PopulateOnDemand property to true so that the child nodes can be

        // dynamically populated.

        newNode.PopulateOnDemand = true;

 

        // Set additional properties for the node.

        newNode.SelectAction = TreeNodeSelectAction.Expand;

 

        // Add the new node to the ChildNodes collection of the parent node.

        node.ChildNodes.Add(newNode);

 

      }

 

    }

 

  }

 

  void PopulateProducts(TreeNode node)

  {

 

    // Query for the products of the current category. These are the values

    // for the third-level nodes.

    DataSet ResultSet = RunQuery("Select ProductName From Products Where CategoryID=" + node.Value);

 

    // Create the third-level nodes.

    if(ResultSet.Tables.Count > 0)

    {

 

      // Iterate through and create a new node for each row in the query results.

      // Notice that the query results are stored in the table of the DataSet.

      foreach (DataRow row in ResultSet.Tables[0].Rows)

      {

 

        // Create the new node.

        TreeNode NewNode = new TreeNode(row["ProductName"].ToString());

 

        // Set the PopulateOnDemand property to false, because these are leaf nodes and

        // do not need to be populated.

        NewNode.PopulateOnDemand = false;

 

        // Set additional properties for the node.

        NewNode.SelectAction = TreeNodeSelectAction.None;

 

        // Add the new node to the ChildNodes collection of the parent node.

        node.ChildNodes.Add(NewNode);

 

      }

 

    }

 

  }

 

  DataSet RunQuery(String QueryString)

  {

 

    // Declare the connection string. This example uses Microsoft SQL Server

    // and connects to the Northwind sample database.

    String ConnectionString = "server=localhost;database=NorthWind;Integrated Security=SSPI";

 

    SqlConnection DBConnection = new SqlConnection(ConnectionString);

    SqlDataAdapter DBAdapter;

    DataSet ResultsDataSet = new DataSet();

 

    try

    {

 

      // Run the query and create a DataSet.

      DBAdapter = new SqlDataAdapter(QueryString, DBConnection);

      DBAdapter.Fill(ResultsDataSet);

 

      // Close the database connection.

      DBConnection.Close();

 

    }

    catch(Exception ex)

    {

 

      // Close the database connection if it is still open.

      if(DBConnection.State == ConnectionState.Open)

      {

        DBConnection.Close();

      }

 

      Message.Text = "Unable to connect to the database.";

 

    }

 

    return ResultsDataSet;

 

  }

 

  protected void Button1_Click(object sender, EventArgs e)

  {

   Response.Write(LinksTreeView.SelectedNode.Value);

  }

</script>

 

<html xmlns="http://www.w3.org/1999/xhtml" >

  <head id="Head1" runat="server">

    <title>TreeView PopulateNodesFromClient Example</title>

</head>

<body>

    <form id="form1" runat="server">

 

      <h3>TreeView PopulateNodesFromClient Example</h3>

 <asp:Button ID="Button1" runat="server" Text="Button" οnclick="Button1_Click" />

      <asp:TreeView id="LinksTreeView"

        Font-Names= "Arial"

        ForeColor="Blue"

        EnableClientScript="true"

        PopulateNodesFromClient="true" 

        OnTreeNodePopulate="PopulateNode"

        runat="server" ExpandDepth="0">

 

        <Nodes>

 

          <asp:TreeNode Text="Inventory"

            SelectAction="Expand" 

            PopulateOnDemand="true" Value="-32768" />

 

        </Nodes>

 

      </asp:TreeView>

 

      <br /><br />

 

      <asp:Label id="Message" runat="server"/>

 

    </form>

  </body>

</html>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值