Never give up - LEO

人 只有在合适的地方 才能体现出最大的价值
  博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

VS2005中Treeview控件的曲折使用历程(一)

Posted on 2007-04-11 15:08  lizhiwen  阅读(3753)  评论(3编辑  收藏  举报

VS2005中自己带了一个Treeview控件,可以不再使用Microsoft命名空间的那个了,本来是件好事。

可我用来用去反而觉得这个新的Treeview控件用起来特bt。

下面我就说说我用这个控件的曲折经历吧,也许是我天资不够聪明才会这样,惭愧啊!

数据源绑定:
我用到了两种方法。
一种是从表中循环获取,下面是msdn上的例子:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>

<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;

  }

</script>

<html>
  <body>
    <form runat="server">
   
      <h3>TreeView PopulateNodesFromClient Example</h3>
   
      <asp:TreeView id="LinksTreeView"
        Font-Name= "Arial"
        ForeColor="Blue"
        EnableClientScript="true"
        PopulateNodesFromClient="true" 
        OnTreeNodePopulate="PopulateNode"
        runat="server">
        
        <Nodes>
       
          <asp:TreeNode Text="Inventory"
            SelectAction="Expand" 
            PopulateOnDemand="true"/>
       
        </Nodes>
       
      </asp:TreeView>
     
      <br><br>
     
      <asp:Label id="Message" runat="server"/>

    </form>
  </body>
</html>

第二种方法就是使用XmlDataSource类。
html文件中:
<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="xml文件路径" XPath="xpath路径">
</asp:XmlDataSource>
cs文件中:
TreeView.DataSourceID = "XmlDataSource1";
TreeView.DataBind();


数据绑定后,就开始设置样式拉。

NodeStyle.
RootNodeStyle、ParentNodeStyle 或 LeafNodeStyle
SelectedNodeStyle.
HoverNodeStyle.
这些样式我都设置了一下,浏览一下页面,感觉还不错。

可用着用着,问题来了。发现每次选中的节点都没有变成我指定的SelectedNodeStyle样式。左找右找找不出问题来,初步发现如果是在服务器端把该节点设置成selected=true,可以看到选择样式,可我现在不想他每次点击节点的时候回发啊。怎么办呢?

我发现每个节点其实都是一个<A>标记,于是就改变主意,在绑定节点时把NavigateUrl属性设置成这样“javascript:fMenuClick()”, Target属性设为空。这样在点击这个节点的时候就是触发一个脚本函数,然后通过脚本函数来改变所点击节点的SelectedNodeStyle样式。改完后,嘿,感觉还不错,预期效果也达到了。

过了几天,页面开发得多了,老是要在各个页面之间转换,又发现了一个问题。当选中一个节点后,这个节点对应的页面已经显示完了,可是下面状态栏的进度条却还没走完,等了半天也不动。我以前遇到过这样的问题,那次是因为页面上有图片,图片没找到,才出现的。可这次我的页面根本就没有图片,也不需要下在文件。我就纳闷,这又是怎么回事呢?

然后我就一个一个的把页面上的控件,脚本去掉,看到底是什么地方影响了。找来找去,尽然是“javascript:fMenuClick()”,把这句去掉,问题就解决了。

我到网上找了半天,也没有找到原因为什么在<a>标记中把href属性设置成调用脚本会出这个问题。如果哪位高手知道原因,还请多多指教。

这个方法也行不通了,怎么办呢。又开始狂找帮助,功夫不负有心人 阿,终于找到第一次为什么没有显示选择样式了。原来HoverNodeStyle会覆盖SelectedNodeStyle的设置,于是我把HoverNodeStyle样式删掉不要,节点选择时SelectedNodeStyle样式出来了。真是太好了,不容易啊!转了一个大圈。