原文:Using a palette from .NET to display properties of multiple AutoCAD objects
本文仅翻译部分内容
经过短暂的插曲,我们又回到了演示如何用.NET在AutoCAD中实现基本用户界面的系列文章。这是目前为止该系列的文章列表:
- Using a modal .NET dialog to display AutoCAD object properties
- Using a modeless .NET dialog to display AutoCAD object properties
- Using a modeless .NET dialog to display properties of multiple AutoCAD objects
在这篇文章中我们将换掉已经在前几篇系列文章中使用的无模式对话框,用AutoCAD内置的palette类(Autodesk.AutoCAD.Windows.PaletteSet)为例来替换它。
为什么要用Paletteset类呢?因为Paletteset类非常炫酷:它提供了停靠(docking),自动隐藏,支持透明度并且修复了我们在无模式对话框中遇到的恼人的焦点相关的问题。
最重要的是,实现这一切基本上不需要花费任何代价——实现它的工作几乎最小的。我从ObjectARX SDK的DockingPalette的示例中复制了大部分的代码,然后删除了我们项目不需要的部分。
下面是更新后的命令的实现。修改真的非常小,因为palette的实现都隐藏在新的TypeViewerPalette类里了。
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;
using CustomDialogs;
namespace CustomDialogs
{
public class Commands : IExtensionApplication
{
static TypeViewerPalette tvp;
public void Initialize()
{
tvp = new TypeViewerPalette();
DocumentCollection dm =
Application.DocumentManager;
dm.DocumentCreated +=
new DocumentCollectionEventHandler(OnDocumentCreated);
foreach (Document doc in dm)
{
doc.Editor.PointMonitor +=
new PointMonitorEventHandler(OnMonitorPoint);
}
}
public void Terminate()
{
try
{
DocumentCollection dm =
Application.DocumentManager;
if (dm != null)
{
Editor ed = dm.MdiActiveDocument.Editor;
ed.PointMonitor -=
new PointMonitorEventHandler(OnMonitorPoint);
}
}
catch (System.Exception)
{
// The editor may no longer
// be available on unload
}
}
private void OnDocumentCreated(
object sender,
DocumentCollectionEventArgs e
)
{
e.Document.Editor.PointMonitor +=
new PointMonitorEventHandler(OnMonitorPoint);
}
private void OnMonitorPoint(
object sender,
PointMonitorEventArgs e
)
{
FullSubentityPath[] paths =
e.Context.GetPickedEntities();
if (paths.Length <= 0)
{
tvp.SetObjectId(ObjectId.Null);
return;
};
ObjectIdCollection idc = new ObjectIdCollection();
foreach (FullSubentityPath path in paths)
{
// Just add the first ID in the list from each path
ObjectId[] ids = path.GetObjectIds();
idc.Add(ids[0]);
}
tvp.SetObjectIds(idc);
}
[CommandMethod("vt",CommandFlags.UsePickSet)]
public void ViewType()
{
tvp.Show();
}
}
}
至于TypeViewerPalette类:我通过从原来的TypeViewerForm类中把SetObjectId[s]()/SetObjectText() 协议迁移过来开始——这是其中最复杂的一部分,涉及通过一个可以从SetObjectText()成员变量暴露我们的面板的内容(我们作为一个用户控件定义并加载)。除了前面说的以外,其它的就只是复制和粘贴了。
这是C #代码:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using Autodesk.AutoCAD.Windows;
using TypeViewer;
namespace CustomDialogs
{
public class TypeViewerPalette
{
// We cannot derive from PaletteSet
// so we contain it
static PaletteSet ps;
// We need to make the textbox available
// via a static member
static TypeViewerControl tvc;
public TypeViewerPalette()
{
tvc = new TypeViewerControl();
}
public void Show()
{
if (ps == null)
{
ps = new PaletteSet("Type Viewer");
ps.Style =
PaletteSetStyles.NameEditable |
PaletteSetStyles.ShowPropertiesMenu |
PaletteSetStyles.ShowAutoHideButton |
PaletteSetStyles.ShowCloseButton;
ps.MinimumSize =
new System.Drawing.Size(300, 300);
ps.Add("Type Viewer 1", tvc);
}
ps.Visible = true;
}
public void SetObjectText(string text)
{
tvc.typeTextBox.Text = text;
}
public void SetObjectIds(ObjectIdCollection ids)
{
if (ids.Count < 0)
{
SetObjectText("");
}
else
{
Document doc =
Autodesk.AutoCAD.ApplicationServices.
Application.DocumentManager.MdiActiveDocument;
DocumentLock loc =
doc.LockDocument();
using (loc)
{
string info =
"Number of objects: " +
ids.Count.ToString() + "\r\n";
Transaction tr =
doc.TransactionManager.StartTransaction();
using (tr)
{
foreach (ObjectId id in ids)
{
Entity ent =
(Entity)tr.GetObject(id, OpenMode.ForRead);
Solid3d sol = ent as Solid3d;
if (sol != null)
{
Acad3DSolid oSol =
(Acad3DSolid)sol.AcadObject;
// Put in a try-catch block, as it's possible
// for solids to not support this property,
// it seems (better safe than sorry)
try
{
string solidType = oSol.SolidType;
info +=
ent.GetType().ToString() +
" (" + solidType + ") : " +
ent.ColorIndex.ToString() + "\r\n";
}
catch (System.Exception)
{
info +=
ent.GetType().ToString() +
" : " +
ent.ColorIndex.ToString() + "\r\n";
}
}
else
{
info +=
ent.GetType().ToString() +
" : " +
ent.ColorIndex.ToString() + "\r\n";
}
}
tr.Commit();
}
SetObjectText(info);
}
}
}
public void SetObjectId(ObjectId id)
{
if (id == ObjectId.Null)
{
SetObjectText("");
}
else
{
Document doc =
Autodesk.AutoCAD.ApplicationServices.
Application.DocumentManager.MdiActiveDocument;
DocumentLock loc =
doc.LockDocument();
using (loc)
{
Transaction tr =
doc.TransactionManager.StartTransaction();
using (tr)
{
DBObject obj =
tr.GetObject(id, OpenMode.ForRead);
SetObjectText(obj.GetType().ToString());
tr.Commit();
}
}
}
}
}
}
你可以从
这里下载源码