zoukankan      html  css  js  c++  java
  • Treeview控件的Node节点延迟加载

    Treeview控件是一个很常用的控件,用于展示资源或者组织结构的时候很方便,通常会在系统启动时进行资源的加载和节点目录的初始化,但在资源较多和层级较深的情况下,所有节点加载出来会耗费太多时间,影响体验,而用户并非每次都关注所有节点,于是想到了一个简单的优化方法:节点的延迟加载...

    解决思路:

    1.在节点加载时,对于下级资源(下级节点)较多的父节点,不必立即添加所有子节点,只需要添加一个无关的空节点,同时显示一个“虚假的”加号(+)效果;

    2.待用户双击该父节点或者是点击节点前的+号,展开该节点的时候,立即去刷新和加载该节点的下级资源。

    实现代码摘录:

     1 List<smBusinessDB> allList = smBusinessDB.GetAll();
     2 resourcePad.DataTree.BeginUpdate();
     3 foreach (smBusinessDB businessDB in allList)
     4 {
     5     //根据业务库属性来决定是否延迟加载
     6     bool IsToLoadAll = !businessDB.BusinessDBInfo.IsLazyLoad;
     7     businessDB.LoadSubResource(IsToLoadAll);
     8     resourcePad.AddNode(null, businessDB as IDataResource);
     9 }
    10 resourcePad.DataTree.EndUpdate();
    11 
    12 /// <summary>
    13 /// 添加资源节点(自动递归添加下级资源节点)
    14 /// </summary>
    15 /// <param name="parentNode">父节点</param>
    16 /// <param name="resource">资源对象</param>
    17 public void AddNode(TreeNode parentNode, IDataResource resource)
    18 {
    19     if (resource == null)
    20     return;
    21     //在资源节点中不显示图层和图层目录
    22     if (resource is smMapLayerDirectory || resource is smMapLayer || resource is smMapBookmark)
    23     return;
    24     //如果不是成果数据源(过程数据源或历史数据源),也不在面板中显示
    25     if (resource is smDatasource && (resource as smDatasource).IsProdectDatasource == false)
    26     return;
    27     TreeNode oNode = CreateNode(resource);
    28     if (parentNode == null)
    29     this.tvResource.Nodes.Add(oNode);
    30     else
    31     parentNode.Nodes.Add(oNode);
    32     foreach (IDataResource sub in resource.SubResource)
    33     {
    34     AddNode(oNode, sub);
    35     //展开第一级节点
    36     if (parentNode == null)
    37         oNode.Expand();
    38     }
    39     //-------- 如果节点未加载下级资源,则添加空节点,以形成“虚假的”+号效果 ----------
    40     if (resource.SubResource.Count == 0 && resource.IsLoadTopChild == false)
    41     {
    42     TreeNode emptyNode = new TreeNode();
    43     oNode.Nodes.Add(emptyNode);
    44     }
    45 }
    46 
    47 ....
    48 //节点展开事件(如果下级未加载,则加载并刷新)
    49 this.tvResource.BeforeExpand += new TreeViewCancelEventHandler(tvResource_BeforeExpand);
    50 
    51 void tvResource_BeforeExpand(object sender, TreeViewCancelEventArgs e)
    52 {
    53     TreeNode selNode = e.Node;
    54     IDataResource nodeResource = selNode.Tag as IDataResource;
    55     if (nodeResource == null)
    56     return;
    57     if (!nodeResource.IsLoadTopChild)
    58     {
    59     nodeResource.LoadSubResource(false);
    60     RefreshNode(nodeResource, true);
    61     selNode.Expand();
    62     }
    63 }

    效果截图:

    1.节点展开前

    2.节点展开后

    以上截图示例中,Treeview控件的第一个root节点是普通加载,第二个root节点是延迟加载。

    问题和待改进之处:

    1.这样的解决方法,在本身无下级节点的时候,也会显示一个“虚假的”+号在节点前面,当用户点击的一瞬间才会消失,有点儿被“欺骗”的感觉,哈哈,但似乎也只能这样,否则不符合延迟加载;

    2.在特别大的数据量的时候,如果某个节点下的子节点非常多,仍然会使加载和刷新该节点时候系统开销增大,影响流畅性,可考虑使用异步或者多线程。

    欢迎补充和拍砖:)

  • 相关阅读:
    兜底方案只能用来兜底,而不能完全依靠它---记一次数据库唯一索引DuplicateKeyException异常的优化
    不注重开发细节,活该你忙!
    二叉树存储
    并查集模板
    684. 冗余连接
    820. 单词的压缩编码
    1102. 得分最高的路径
    滑动窗口模板
    古道西风“瘦马”
    西江月·凉凉
  • 原文地址:https://www.cnblogs.com/qingteng1983/p/2815616.html
Copyright © 2011-2022 走看看