NX二次开发-BlockUI树列表快速插入多个节点

适用版本:NX 7.5及以上版本

一、概述

在NX二次开发中,我们经常使用BlockUI来设计界面,树列表控件(Tree List)是非常常用的控件之一 ,可以创建表示节点层次结构的树-节点结构,并将回调操作分配给树和节点的事件,效果像部件导航器一样。

二、功能说明

        如果显示指定目录下的子目录的名称,我们常用添加节点的方法如下:
 

//记录最后一个节点
 NXOpen.BlockStyler.Node afterNode = null;
 //遍历目录
 foreach (var directory in directoryInfo.GetDirectories())
 {
     //创建节点
     var parentNode = mToRecognizeTree.CreateNode(directory.Name);
     //设置图标
     parentNode.DisplayIcon = "folder_closed";
     parentNode.SelectedIcon = "folder_closed";
     //插入节点
     mToRecognizeTree.InsertNode(parentNode, null, afterNode, NXOpen.BlockStyler.Tree.NodeInsertOption.AlwaysLast);
     //更新最后一个节点记录
     afterNode = parentNode;
 }

      如果需要显示子目录下的孙目录的名称,这个时候我们的代码就需要修改成如下:
 

//记录最后一个节点
 NXOpen.BlockStyler.Node afterNode = null;
 //遍历目录
 foreach (var directory in directoryInfo.GetDirectories())
 {
     //创建节点
     var parentNode = mToRecognizeTree.CreateNode(directory.Name);
     //设置图标
     parentNode.DisplayIcon = "folder_closed";
     parentNode.SelectedIcon = "folder_closed";
     //插入节点
     mToRecognizeTree.InsertNode(parentNode, null, afterNode, NXOpen.BlockStyler.Tree.NodeInsertOption.AlwaysLast);
     //操作子目录
     NXOpen.BlockStyler.Node subAfterNode = null;
     foreach (var subDirectory in directory.GetDirectories())
     {
         var subNode = mToRecognizeTree.CreateNode(subDirectory.Name);
         subNode.DisplayIcon = "folder_closed";
         subNode.SelectedIcon = "folder_closed";
         mToRecognizeTree.InsertNode(subNode, parentNode, subAfterNode, NXOpen.BlockStyler.Tree.NodeInsertOption.AlwaysLast);
         subAfterNode = subNode;
     }
     //更新最后一个节点记录
     afterNode = parentNode;
 }

从上图代码可以看出以下几点不足:

1.需要定义多个记录最后一个节点;

2.父节点和最后一个节点参数容易出现手误,导致程序出现BUG;

3设置图标导致代码行增加影响阅读。

本文采用扩展方法后的效果如下:
 

foreach (var parentDir in mToRecognizeTree.InsertNodes(
     directoryInfo.GetDirectories(),//数据源
     obj => obj.Name,//选择显示文本的函数
     obj => "folder_closed"))//选择显示图标的函数
 {
     //TODO::

     foreach (var subDir in mToRecognizeTree.InsertNodes(
         parentDir.Key,//父节点
         parentDir.Value.GetDirectories(),//数据源
         obj => obj.Name, //选择显示文本的函数
         obj => "folder_closed")) //选择显示图标的函数
     {
         //TODO::

     }
 } }

上图代码的InsertNodes方法的实现如下:

using System.Collections.Generic;
using NXOpen.BlockStyler;

namespace Bizca
{
    public static class TreeControlHelper
    {
        /// <summary>
        /// 插入节点数据
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型。</typeparam>
        /// <param name="tree">指定树列表</param>
        /// <param name="parentNode">指定父节点</param>
        /// <param name="source">数据源</param>
        /// <param name="textSelector">用于从每个元素中提取显示文本的函数。</param>
        /// <param name="action">用于从每个元素中创建节点后初始化的函数,比如设置图标、绑定数据等。</param>
        /// <returns></returns>
        public static IEnumerable<KeyValuePair<Node, TSource>> InsertNodes<TSource>(
            this Tree tree,
            Node parentNode,
            IEnumerable<TSource> source,
            System.Func<TSource, string> textSelector,
            System.Action<TSource, Node> action = null)
        {
            //验证参数
            if (source == null)
                throw new System.ArgumentNullException(nameof(source));
            if (textSelector == null)
                throw new System.ArgumentNullException(nameof(textSelector));
            //查找最后一个节点
            Node afterNode = parentNode == null ? tree.RootNode : parentNode.FirstChildNode;
            while (afterNode != null)
            {
                Node tempNode = afterNode.NextSiblingNode;
                if (tempNode == null) break;
                afterNode = tempNode;
            }
            //遍历源
            foreach (var element in source)
            {
                //创建节点
                Node newNode = tree.CreateNode(textSelector.Invoke(element));
                //初始化,比如设置图标、绑定数据等。
                action?.Invoke(element, newNode);
                //插入节点
                tree.InsertNode(newNode, parentNode, afterNode, Tree.NodeInsertOption.AlwaysLast);
                //更新最后一个节点记录
                afterNode = newNode;
                //返回集合
                yield return new KeyValuePair<Node, TSource>(newNode, element);
            }
        }

        /// <summary>
        /// 插入节点数据
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型。</typeparam>
        /// <param name="tree">指定树列表</param>
        /// <param name="parentNode">指定父节点</param>
        /// <param name="source">数据源</param>
        /// <param name="textSelector">用于从每个元素中提取显示文本的函数。</param>
        /// <param name="iconSelector">用于从每个元素中提取显示图标的函数。</param>
        /// <returns></returns>
        public static IEnumerable<KeyValuePair<Node, TSource>> InsertNodes<TSource>(
            this Tree tree,
            Node parentNode,
            IEnumerable<TSource> source,
            System.Func<TSource, string> textSelector,
            System.Func<TSource, string> iconSelector)
        {
            System.Action<TSource, Node> action = (eSource, newNode) =>
            {
                if (iconSelector != null)
                {
                    string icon = iconSelector.Invoke(eSource);
                    newNode.DisplayIcon = icon;
                    newNode.SelectedIcon = icon;
                }
            };
            return InsertNodes(tree, parentNode, source, textSelector, action);
        }
    }
}

三、总结

      将TreeControlHelper类封装成基础库重复调用,这种方式可以避免以上出现的不足,快速的插入多个或多级节点到树列表空间中,不容易出现BUG,便于阅读和调试。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值