适用版本: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,便于阅读和调试。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)