非常感谢DevTech美国团队的Fenton Webb,他提供的代码是这篇文章中代码的基础。谢谢,Fents! :-)
Fenton 最近为一位想用定制的树视图来显示AutoCAD中的图纸集管理器内的信息的ADN会员写了个例子。Fenton的版本用了WPF, 我简单化一下,使用了WinForms,但可能后续也会做一个使用WPF的例子。
我对Fenton的代码做了些修改,所以,如果有任何错误,很可能是我的而不是他的。我只是填充了一些类型的数据,但我没有操作这些数据(我不知道是否有任何真正的需要),别人可能需要做进一步的工作来使用这些数据,甚至把代码截取出来。
总之,下面是C#代码。为使代码运行,将需要增加对acsmcomponents18.tlb (或acsmcomponents17.tlb如果使用AutoCAD 2007-2009年)的参考,以及 AcMgd.dll, AcDbMgd.dll 和Visual Studio提供的.NET组件。
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using acApp =
Autodesk.AutoCAD.ApplicationServices;
using ACSMCOMPONENTS18Lib;
using System.Windows.Forms;
using System;
namespace MyApplication
{
public class Commands
{
static PaletteSet ps = null;
static UserControl1 userControl = null;
[CommandMethod("SSTREE")]
public void PopulateCustomSheetTree()
{
// Check the state of the paletteset
if (ps == null)
{
// Then create it
ps = new PaletteSet("Custom Sheet Tree");
userControl = new UserControl1();
ps.Add("MySheetView", userControl);
}
ps.Visible = true;
// Get the AutoCAD Editor
Editor ed =
acApp.Application.DocumentManager.MdiActiveDocument.Editor;
// Get the SheetSet Manager
AcSmSheetSetMgr mgr = new AcSmSheetSetMgr();
// Create a new SheetSet Database
AcSmDatabase db = new AcSmDatabase();
// Try and load a default DST file...
try
{
db =
mgr.OpenDatabase(
@"C:/Program Files/Autodesk/AutoCAD 2011/Sample/" +
@"Sheet Sets/Architectural/IRD Addition.dst",
true
);
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
return;
}
// Lock the db for processing
db.LockDb(db);
AcSmSheetSet ss = db.GetSheetSet();
// Create a root item in the TreeView,
// the name of the SheetSet
TreeNode root = new TreeNode(ss.GetName());
userControl.treeView1.Nodes.Add(root);
ProcessEnumerator(ss.GetSheetEnumerator(), root);
db.UnlockDb(db, true);
mgr.Close(db);
}
void ProcessEnumerator(IAcSmEnumComponent iter, TreeNode root)
{
IAcSmComponent item = iter.Next();
while (item != null)
{
string type = item.GetTypeName();
switch (type)
{
case "AcSmSubset":
try
{
AcSmSubset subset = (AcSmSubset)item;
string subName = subset.GetName();
if (!String.IsNullOrEmpty(subName))
{
TreeNode tn = AddTreeNode(root, subName);
IAcSmEnumComponent enumerator =
(IAcSmEnumComponent)subset.GetSheetEnumerator();
ProcessEnumerator(enumerator, tn);
}
}
catch { }
break;
case "AcSmSheet":
try
{
AcSmSheet sh = (AcSmSheet)item;
string shName = sh.GetName();
if (!String.IsNullOrEmpty(shName))
{
TreeNode tn = AddTreeNode(root, shName);
IAcSmEnumComponent enumerator =
(IAcSmEnumComponent)sh.GetSheetViews();
ProcessEnumerator(enumerator, tn);
}
}
catch { }
break;
case "AcSmSheetViews":
try
{
AcSmSheet sh = (AcSmSheet)item;
string shName = sh.GetName();
if (!String.IsNullOrEmpty(shName))
{
TreeNode tn = AddTreeNode(root, shName);
IAcSmEnumComponent enumerator =
(IAcSmEnumComponent)sh.GetSheetViews();
ProcessEnumerator(enumerator, tn);
}
}
catch { }
break;
case "AcSmSheetView":
try
{
AcSmSheetView sv = (AcSmSheetView)item;
string svName = sv.GetName();
if (!String.IsNullOrEmpty(svName))
AddTreeNode(root, svName);
}
catch { }
break;
case "AcSmCustomPropertyValue":
AcSmCustomPropertyValue pv =
(AcSmCustomPropertyValue)item;
AddTreeNode(
root,
"Custom property value: " + pv.GetValue().ToString()
);
break;
case "AcSmObjectReference":
AcSmObjectReference or =
(AcSmObjectReference)item;
AddTreeNode(
root,
"Object reference: " +
or.GetReferencedObject().GetTypeName()
);
break;
case "AcSmCustomPropertyBag":
try
{
AcSmCustomPropertyBag bag =
(AcSmCustomPropertyBag)item;
TreeNode tn = AddTreeNode(root, "Custom property bag");
IAcSmEnumComponent enumerator =
(IAcSmEnumComponent)bag.GetPropertyEnumerator();
ProcessEnumerator(enumerator, tn);
}
catch { }
break;
case "AcSmAcDbLayoutReference":
AcSmAcDbLayoutReference lr =
(AcSmAcDbLayoutReference)item;
AddTreeNode(
root,
"Layout reference: " + lr.GetName()
);
break;
case "AcSmFileReference":
AcSmFileReference fr = (AcSmFileReference)item;
AddTreeNode(
root,
"Layout reference: " + fr.GetFileName()
);
break;
case "AcSmAcDbViewReference":
AcSmAcDbViewReference vr = (AcSmAcDbViewReference)item;
AddTreeNode(
root,
"View reference: " + vr.GetName()
);
break;
case "AcSmResources":
try
{
AcSmResources res = (AcSmResources)item;
TreeNode tn = AddTreeNode(root, "Resources");
IAcSmEnumComponent enumerator =
(IAcSmEnumComponent)res.GetEnumerator();
ProcessEnumerator(enumerator, tn);
}
catch { }
break;
default:
Document doc =
acApp.Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
ed.WriteMessage("/nMissed Type = " + type);
break;
}
item = iter.Next();
}
}
private TreeNode AddTreeNode(TreeNode root, string name)
{
// Create a new node on the tree view
TreeNode node = new TreeNode(name);
// Add it to what we have
root.Nodes.Add(node);
return node;
}
}
}
您将需要添加一个新的UserControl到您的项目中的一个TreeView中, 并设置Dock属性为fill(填补)。一定要保持默认名称UserControl1和treeView1。除此之外,没有任何用户界面的工作需要作。
下面是我们运行SSTREE命令和把硬编码的DST导入到SheetSet管理器(用SSM命令显示)进行的比较:
显然你可以多做一些工作,使两个用户界面看起来相同(图标等),但那是更多的关于递归解析SheetSet树的问题,而不是我侧重要介绍的东西。如果您在用其它DST文件时遇到任何问题,一定要出来发表评论。