zoukankan      html  css  js  c++  java
  • [原创]FineUI秘密花园(二十三) — 树控件概述

    树控件用来展示具有层次结构的数据。前面在介绍下拉列表和表格控件时,我们已经接触到模拟树的下拉列表和模拟树的表格,今天我们就来讲解真正的树控件。

    标签创建的树控件

    我们可以直接在ASPX页面中创建树控件,非常直观,比如:

       1:  <ext:Tree ID="Tree1" Width="500px" ShowHeader="true" Title="树控件(内联)" runat="server">
       2:      <Nodes>
       3:          <ext:TreeNode Text="中国" Expanded="true">
       4:              <ext:TreeNode Text="河南省" Expanded="true">
       5:                  <ext:TreeNode Text="驻马店市" NodeID="zhumadian">
       6:                      <ext:TreeNode Text="遂平县" Leaf="false" NodeID="suiping">
       7:                          <ext:TreeNode Text="槐树乡" Leaf="false" NodeID="huaishu">
       8:                              <ext:TreeNode Text="陈庄村" Leaf="true" NodeID="chenzhuang">
       9:                              </ext:TreeNode>
      10:                          </ext:TreeNode>
      11:                      </ext:TreeNode>
      12:                  </ext:TreeNode>
      13:                  <ext:TreeNode Text="漯河市" Leaf="true" NodeID="luohe" />
      14:              </ext:TreeNode>
      15:              // 省略其他节点...
      16:          </ext:TreeNode>
      17:      </Nodes>
      18:  </ext:Tree>

    显示效果如下图所示:

    image

    由此可见,一棵树是由TreeNode节点嵌套而来的,下面就来看下TreeNode有哪些属性:

    树节点的常用属性

    • Text:树节点文本
    • NodeID:树节点ID
    • Leaf:是否叶子节点
    • Enabled:是否可用
    • Expanded:是否展开
    • NavigateUrl:链接地址
    • Target:链接目标
    • Icon:预定义图标
    • IconUrl:图标地址
    • ToolTip:提示文本
    • SingleClickExpand:单击可切换节点的折叠展开状态

    由此可见,树节点可以禁用、可以渲染为超链接、可以定义图标、可以设置提示文本。

    可以回发的树节点

    • EnablePostBack:是否可以回发(单击树节点)
    • OnClientClick:点击按钮时需要执行的客户端脚本
    • CommandName:命令名称
    • CommandArgument:命令参数

    可见,树节点也可以作为一个按钮来触发后台事件,只不过这个事件定义是在树控件上。而CommandName和CommandArgument则类似于表格控件中LinkButtonField定义的同名属性。

    带复选框的树节点

    • Checked:是否选中
    • EnableCheckBox:是否启用复选框
    • AutoPostBack:是否自动回发(改变复选框状态)

    可见,树节点也可以作为一个复选框来触发后台事件。这里AutoPostBack属性就类似于表格控件中CheckBoxField定义的同名属性。

    可以回发的树节点

    通过一个简单示例来讲解其用法:

       1:  <ext:Tree ID="Tree1" Width="500px" OnNodeCommand="Tree1_NodeCommand" ShowHeader="true"
       2:      Title="树控件" runat="server">
       3:      <Nodes>
       4:          <ext:TreeNode Text="中国" Expanded="true">
       5:              <ext:TreeNode Text="河南省" Expanded="true">
       6:                  <ext:TreeNode Text="驻马店市(点击回发)" EnablePostBack="true" Expanded="true" NodeID="Zhumadian">
       7:                      <ext:TreeNode Text="遂平县(点击回发)" EnablePostBack="true" NodeID="Suiping">
       8:                      </ext:TreeNode>
       9:                      <ext:TreeNode Text="西平县(点击回发)" EnablePostBack="true" NodeID="Xiping">
      10:                      </ext:TreeNode>
      11:                  </ext:TreeNode>
      12:                  <ext:TreeNode Text="漯河市" Enabled="true" NodeID="Luohe" />
      13:              </ext:TreeNode>
      14:              // 省略其他节点...
      15:          </ext:TreeNode>
      16:      </Nodes>
      17:  </ext:Tree>

    这里有几个关键点:

    1. 为树控件注册节点命令处理函数;
    2. 在需要点击回发的树节点上启用EnablePostBack;
    3. 还可以指定CommandName或者CommandArgument(本例中未用到)。

    来看下后台处理函数:

       1:  protected void Tree1_NodeCommand(object sender, FineUI.TreeCommandEventArgs e)
       2:  {
       3:      labResult.Text = "你点击了树节点:" + e.Node.Text;
       4:  }

    运行截图:

    image

    带复选框的树节点

    带复选框的树节点只需要启用EnableCheckBox即可,下面的例子我们会更进一步,使用自动回发的复选框树节点来全选/反选所有的子节点,运行效果如下图所示:

    image

    当选中河南省前面的复选框时,会回发页面并选中河南省下面所有子节点的复选框,这是怎么做到的呢?

    先看一下页面标签:

       1:   <ext:Tree ID="Tree1" OnNodeCheck="Tree1_NodeCheck" Width="500px" ShowHeader="true"
       2:      Title="树控件" runat="server">
       3:      <Nodes>
       4:          <ext:TreeNode Text="中国" EnableCheckBox="true" AutoPostBack="true" Expanded="true">
       5:              <ext:TreeNode AutoPostBack="true" Text="河南省" EnableCheckBox="true" Expanded="true">
       6:                  <ext:TreeNode Text="驻马店市" AutoPostBack="true" EnableCheckBox="true" NodeID="zhumadian">
       7:                      <ext:TreeNode Text="遂平县" AutoPostBack="true" EnableCheckBox="true" NodeID="Suiping">
       8:                      </ext:TreeNode>
       9:                      <ext:TreeNode Text="西平县" AutoPostBack="true" EnableCheckBox="true" NodeID="Xiping">
      10:                      </ext:TreeNode>
      11:                  </ext:TreeNode>
      12:                  <ext:TreeNode Text="漯河市" AutoPostBack="true" EnableCheckBox="true" NodeID="luohe" />
      13:              </ext:TreeNode>
      14:              // 省略其他节点...
      15:          </ext:TreeNode>
      16:      </Nodes>
      17:  </ext:Tree>

    这里有几个关键点:

    1. 为树控件注册节点选中处理函数;
    2. 在需要显示复选框的节点上启用EnableCheckBox;
    3. 在需要自动回发复选框的树节点上启用AutoPostBack;

    再来看下选中节点复选框的处理函数:

       1:  protected void Tree1_NodeCheck(object sender, FineUI.TreeCheckEventArgs e)
       2:  {
       3:      if (e.Checked)
       4:      {
       5:          Tree1.CheckAllNodes(e.Node.Nodes);
       6:      }
       7:      else
       8:      {
       9:          Tree1.UncheckAllNodes(e.Node.Nodes);
      10:      }
      11:  }

    这里调用了CheckAllNodes函数来选中所有的子节点,当然我们也可以手工递归所有的子节点来完成此操作。

    下面是使用递归的方式来完成此操作的参考代码:

       1:  protected void Tree1_NodeCheck(object sender, FineUI.TreeCheckEventArgs e)
       2:  {
       3:        if (!e.Node.Leaf)
       4:        {
       5:            CheckTreeNode(e.Node.Nodes, e.Checked);
       6:        }
       7:  }
       8:   
       9:  private void CheckTreeNode(TreeNodeCollection nodes, bool isChecked)
      10:  {
      11:      foreach (TreeNode node in nodes)
      12:      {
      13:          node.Checked = isChecked;
      14:          if (!node.Leaf)
      15:          {
      16:              CheckTreeNode(node.Nodes, isChecked);
      17:          }
      18:      }
      19:  } 

    延迟加载的树节点

    在上面这些例子中,不知道你有没有发现一个细节,有时我们为子节点设置了Leaf=true,有时又没有设置,不过似乎都能正常运行,这是怎么回事?

    其实,是否为树节点设置Leaf属性都可以,因为FineUI内部会重新递归所有的子节点,将拥有子节点的节点Leaf属性设为false,反之设为true。控制这一行为的属性就是AutoLeafIdentification(默认值为true)。

    如果将树控件的AutoLeafIdentification设为false,则我们就需要为每一个子节点设置Leaf=true(默认为false),如果没有为一个理应成为子节点的节点设置Leaf=true,则此节点就会被渲染为一个可折叠展开的父节点,展开此节点时就会触发树控件的NodeExpand事件。

    正好,我们可以利用这一特性来完成延迟加载的树节点,是不是很巧妙。下面通过一个示例来演示。

    先看页面的标签:

       1:  <ext:Tree ID="Tree1" EnableArrows="true" OnNodeExpand="Tree1_NodeExpand" Width="500px"
       2:      ShowHeader="true" Title="延迟加载的树控件" AutoLeafIdentification="false" runat="server">
       3:      <Nodes>
       4:          <ext:TreeNode Text="中国" Expanded="true">
       5:              <ext:TreeNode Text="河南省" Expanded="true">
       6:                  <ext:TreeNode Text="驻马店市(此节点延迟加载)" NodeID="zhumadian">
       7:                  </ext:TreeNode>
       8:                  <ext:TreeNode Text="漯河" NodeID="luohe" Leaf="true" />
       9:              </ext:TreeNode>
      10:              // 省略其他节点...
      11:          </ext:TreeNode>
      12:      </Nodes>
      13:  </ext:Tree>

    这里有几个关键点:

    1. 为树控件注册节点展开处理函数;
    2. 为树控件设置AutoLeafIdentification=false;
    3. 为真正的子节点设置Leaf=true;
    4. 需要延迟加载的树节点不要设置Leaf属性(即默认为false)。

    先来看下页面第一次打开的截图:

    image

    此时“驻马店市”下面并没有子节点,因此展开此节点时会触发树控件的节点展开事件。

    下面来看下节点展开事件的处理函数:

       1:  protected void Tree1_NodeExpand(object sender, FineUI.TreeExpandEventArgs e)
       2:  {
       3:      DynamicAppendNode(e.Node);
       4:  }
       5:   
       6:  private void DynamicAppendNode(TreeNode parentNode)
       7:  {
       8:      parentNode.Expanded = true;
       9:   
      10:      TreeNode node = null;
      11:      switch (parentNode.NodeID)
      12:      {
      13:          case "zhumadian":
      14:              node = new TreeNode();
      15:              node.Text = "遂平县";
      16:              node.Leaf = false;
      17:              node.NodeID = "suiping";
      18:              parentNode.Nodes.Add(node);
      19:   
      20:              node = new TreeNode();
      21:              node.Text = "西平县";
      22:              node.Leaf = true;
      23:              node.NodeID = "xiping";
      24:              parentNode.Nodes.Add(node);
      25:              break;
      26:          case "suiping":
      27:              node = new TreeNode();
      28:              node.Text = "槐树乡";
      29:              node.Leaf = false;
      30:              node.NodeID = "huaishu";
      31:              parentNode.Nodes.Add(node);
      32:              break;
      33:          case "huaishu":
      34:              node = new TreeNode();
      35:              node.Text = "陈庄村";
      36:              node.Leaf = true;
      37:              node.NodeID = "chenzhuang";
      38:              parentNode.Nodes.Add(node);
      39:              break;
      40:      }
      41:  }

    这段代码不仅处理展开“驻马店市”的情况,而且处理下面的层次结构,通过NodeID进行关联,大家可以认真分析下这段代码。

    下面是运行截图:

    image

    注:第一次展开“驻马店市”之后,就向其中添加了子节点,所以折叠后再次展开此节点就不会触发节点展开事件了。

    小结

    本章我们介绍了树控件的各种用法,树节点不仅可以被渲染为普通文本、超链接、可回发的文本,而且可以渲染为带自动回发复选框的文本,同时我们还讲解了延迟树节点的用法。

    下一篇文章我们会介绍如何将各种不同的数据源绑定到将树控件。

    注:《FineUI秘密花园》系列文章由三生石上原创,博客园首发,转载请注明出处。文章目录 官方论坛

  • 相关阅读:
    使用adb命令报错:解决办法
    appium+python+unittest自动化测试
    HTML自动化测试报告
    彻底解决appium 自动化测试时总是自动安装appium android input manager for unicode的问题
    selenium+python获取文本内容
    jenkins+robotframework中的Rebots Results不显示报告内容的问题
    robotframework+appium使用时的思考
    selenium unittest框架的断言知识
    jenkins配置问题三----用例运行pass,但是测试结果显示failure
    小程序中target与currentTarget的取值问题
  • 原文地址:https://www.cnblogs.com/sanshi/p/2780101.html
Copyright © 2011-2022 走看看