The code in my first post was derived from several posts here at theSwamp.org and the .NET Autodesk Discussion Group.
I've also tried to implement a version of code that I derived from the book I purchased VB.NET Programming for AutoCAD and it's Chapter 9 on cloning. It uses the DeepClone method and not the DeepCloneObjects method.
I get the compile error using the DeepClone method on the following code:
Error 1 Cannot implicitly convert type 'Autodesk.AutoCAD.DatabaseServices.DBObject' to 'Autodesk.AutoCAD.DatabaseServices.BlockTableRecord'. An explicit conversion exists (are you missing a cast?)
[CommandMethod("clone", CommandFlags.UsePickSet |
CommandFlags.Redraw |
CommandFlags.Modal)]
static public void CloneTest()
{
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Editor ed = acDoc.Editor;
Database acCurDb = acDoc.Database;
try
{
PromptSelectionResult selectionRes = ed.SelectImplied();
// If there's no pickfirst set available...
if (selectionRes.Status == PromptStatus.Error)
{
// ... ask the user to select entities
PromptSelectionOptions selectionOpts = new PromptSelectionOptions();
selectionOpts.MessageForAdding = "\nSelect objects to list: ";
selectionRes = ed.GetSelection(selectionOpts);
}
else
{
// If there was a pickfirst set, clear it
ed.SetImpliedSelection(new ObjectId[0]);
}
// If the user has not cancelled...
if (selectionRes.Status == PromptStatus.OK)
{
// ... take the selected objects one by one
Transaction tr = acDoc.TransactionManager.StartTransaction();
try
{
ObjectId[] objIds = selectionRes.Value.GetObjectIds();
foreach (ObjectId objId in objIds)
{
DBObject obj = tr.GetObject(objId, OpenMode.ForRead);
Entity ent = (Entity)obj;
if (ent is BlockReference)
{
BlockReference blkRef = obj as BlockReference;
// Open the Block table for read
BlockTable acBlkTbl;
acBlkTbl = tr.GetObject(acCurDb.BlockTableId,
OpenMode.ForWrite) as BlockTable;
// Step through the Block table record
foreach (ObjectId btrId in acBlkTbl)
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(btrId,
OpenMode.ForWrite,
false);
if (!btr.IsLayout && blkRef.Name == btr.Name)
{
BlockTableRecord btrClone = new BlockTableRecord();
IdMapping idMap = new IdMapping();
btrClone = btr.DeepClone(acBlkTbl, idMap, true);
btrClone.Name = btr.Name + "-Clone";
acBlkTbl.Add(btrClone);
tr.AddNewlyCreatedDBObject(btrClone, true); }
acCurDb.Dispose();
}
blkRef.Dispose();
}
}
tr.Commit();
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage(ex.Message);
tr.Abort();
}
}
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage(ex.Message);
}
}
I am guessing my first post is closer to being correct. But I have a couple of questions:
1. My first post seems to be cloning the block reference and not the block definition like the code in highlighted in this post. From my AutoLISP and AutoCAD experience it would seem that I want to clone the block definition like the code in this post. Which is correct?
2. If my code from my first post is more correct, how to I apply the Name of the new block Definition?
This post from the .NET Autodesk Discussion Group has been a big influence on the code in my first post:
http://discussion.autodesk.com/forums/thread.jspa?messageID=6074184�Any and all help is appreciated!