适用版本: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

{

///

/// 插入节点数据

///

/// source 中的元素的类型。

/// 指定树列表

/// 指定父节点

/// 数据源

/// 用于从每个元素中提取显示文本的函数。

/// 用于从每个元素中创建节点后初始化的函数,比如设置图标、绑定数据等。

///

public static IEnumerable> InsertNodes(

this Tree tree,

Node parentNode,

IEnumerable source,

System.Func textSelector,

System.Action 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(newNode, element);

}

}

///

/// 插入节点数据

///

/// source 中的元素的类型。

/// 指定树列表

/// 指定父节点

/// 数据源

/// 用于从每个元素中提取显示文本的函数。

/// 用于从每个元素中提取显示图标的函数。

///

public static IEnumerable> InsertNodes(

this Tree tree,

Node parentNode,

IEnumerable source,

System.Func textSelector,

System.Func iconSelector)

{

System.Action 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,便于阅读和调试。

参考链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。