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

文章介绍了在NX二次开发中如何使用TreeList控件创建节点层次结构,并通过扩展方法简化了添加多级节点的代码,提高了代码可读性和减少了错误的可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

适用版本: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,便于阅读和调试。

<think>好的,用户现在问的是关于NX二次开发中的“树列表”和“集列表”。我需要先确认这两个术语的具体含义,因为在NX二次开发中,可能有些术语是用户自己翻译或者特定版本的叫法。 首先,回想之前用户的问题是关于Block UI Editor生成C++代码的设置,现在转向了树列表和集列表,可能用户在使用NXUI设计或者数据管理功能时遇到了问题。需要确定这两个组件在NX中的官方名称和用途。 树列表,可能指的是Tree List控件,用于显示层次结构数据,比如装配结构或者分类信息。在Block UI中,Tree List可以让用户展开或折叠节点,进行选择操作。集列表可能是指Collection List,用于显示一组项目的列表,允许多选或单选,比如特征列表或组件列表。 接下来需要验证这些控件的正确名称和用法。查阅NX Open API文档或者Block UI Editor的官方资料,确认Tree List和Collection List是否存在,以及它们在C++中的使用方法。例如,Tree List在Block UI中对应的类是哪个,如何绑定数据,事件处理等。 用户可能需要了解如何创建这些列表,如何填充数据,如何处理用户的选择事件。此外,集列表可能有特定的数据绑定方式,比如关联到特征或组件集合。需要分步骤介绍如何在Block UI中添加这些控件,并在C++代码中操作它们。 还要考虑用户可能的实际应用场景,比如在自定义对话框中显示装配结构(树列表)或让用户选择多个特征(集列表)。需要给出具体的代码示例,说明如何初始化控件、更新数据、响应事件。 同时,注意用户可能对NX的术语不熟悉,比如“集列表”是否指代Collection List还是其他控件,需要明确说明避免混淆。另外,提醒用户注意不同NX版本之间的差异,以及需要引用的头文件和命名空间。 最后,总结使用这些控件的最佳实践,比如数据绑定的方法、内存管理、事件处理的注意事项,帮助用户避免常见错误。</think>在NX二次开发中,**树列表(Tree List)** 和 **集列表(Collection List)** 是两种常见的UI控件,用于在自定义对话框中展示层次化数据或集合数据。以下是它们的定义、用途及C++开发中的实现方法: --- ### **1. 树列表(Tree List)** #### **功能** - 树列表以**树形结构**展示层次化数据(如装配结构、分类目录等),支持节点的展开/折叠、多级嵌套和交互操作(如选中、勾选等)。 - 常用于需要展示父子关系或层级关系的场景(例如:装配树、参数分类等)。 #### **Block UI Editor中的实现** 1. **添加控件**: - 在Block UI设计界面中,拖放 **Tree** 或 **Tree List** 控件到对话框。 - 设置属性:`Label`(标题)、`ShowCheckboxes`(显示勾选框)、`SelectionMode`(单选/多选)等。 2. **C++代码绑定**: ```cpp // 获取Tree控件句柄 NXOpen::BlockStyler::Tree* tree = theDialog->GetTree("treeControlId"); // 添加根节点和子节点 std::vector<NXOpen::BlockStyler::Node*> rootNodes; NXOpen::BlockStyler::Node* rootNode = tree->CreateNode("Root"); rootNode->SetColumnDisplayText(0, "Root Node"); // 设置列文本 rootNode->AddChild(tree->CreateNode("Child Node")); rootNodes.push_back(rootNode); // 更新树数据 tree->UpdateNodes(rootNodes); ``` 3. **事件响应**: ```cpp // 注册节点选择事件回调 tree->AddSelectHandler(make_callback(this, YourClass::OnTreeSelect)); // 处理选择事件 void YourClass::OnTreeSelect(NXOpen::BlockStyler::Tree* tree, NXOpen::BlockStyler::Node* node) { if (node->IsSelected()) { // 处理选中的节点 } } ``` --- ### **2. 集列表(Collection List)** #### **功能** - 集列表以**平铺列表**形式展示一组数据(如特征列表、组件列表等),支持单选、多选、排序和过滤。 - 常用于需要用户从集合中选择一个或多个项目的场景(例如:选择特征、选择组件)。 #### **Block UI Editor中的实现** 1. **添加控件**: - 拖放 **Collection List** 或 **List Box** 控件到对话框。 - 设置属性:`ListItems`(初始项)、`SelectionMode`(单选/多选)等。 2. **C++代码绑定**: ```cpp // 获取集列表句柄 NXOpen::BlockStyler::ListBox* list = theDialog->GetListBox("listControlId"); // 添加列表项 std::vector<std::string> items = {"Item 1", "Item 2", "Item 3"}; list->SetListItems(items); // 设置选中项 list->SetSelectedItems({"Item 1"}); ``` 3. **事件响应**: ```cpp // 注册选择事件回调 list->AddSelectHandler(make_callback(this, YourClass::OnListSelect)); // 处理选择事件 void YourClass::OnListSelect(NXOpen::BlockStyler::ListBox* list) { std::vector<int> selectedIndices = list->GetSelectedIndices(); // 根据选中索引获取数据 } ``` --- ### **核心区别与使用场景** | **控件** | **数据结构** | **交互场景** | **典型应用** | |----------------|-------------|----------------------------------|----------------------------| | **树列表** | 层次化数据 | 父子关系展开、多级选择 | 装配导航、参数分类、目录树 | | **集列表** | 平铺数据 | 快速单选/多选、批量操作 | 特征选择、组件列表、文件列表 | --- ### **开发注意事项** 1. **数据绑定效率**: - 树列表初始化复杂数据时,需分批加载避免卡顿。 - 集列表数据量大时,建议启用虚拟模式(仅加载可见项)。 2. **事件处理**: - 树列表需处理节点展开/折叠事件以动态加载子节点- 集列表需支持搜索过滤功能(通过`AddFilter`方法)。 3. **与NX对象关联**: - 可通过`Node::UserData`或`ListBoxItem::UserData`绑定NX对象(如`TaggedObject*`),便于后续操作。 --- ### **示例代码(树列表动态加载装配结构)** ```cpp void BuildAssemblyTree(NXOpen::BlockStyler::Tree* tree, NXOpen::Assemblies::Component* parentComp) { std::vector<NXOpen::Assemblies::Component*> children = parentComp->GetChildren(); for (auto child : children) { NXOpen::BlockStyler::Node* node = tree->CreateNode(child->Name()); node->SetUserData(child); // 绑定组件对象 BuildAssemblyTree(tree, child); // 递归加载子组件 parentNode->AddChild(node); } } ``` 通过上述方法,可以快速实现基于NX Open C++的树列表和集列表功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值