Changing the colour of nested AutoCAD entities through .NET
Someone asked me earlier today how to iteratively change the color of entities inside blocks.
The following code uses a recursive helper function to iterate down through the contents of a block, changing the various entities (other than block references, for which we simply recurse) to a specified colour.
Here's the C# code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Colors;
namespace BlockTest
{
public class BlockCmds
{
[CommandMethod("CC")]
public void ChangeColor()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptIntegerResult pr =
ed.GetInteger(
"\nEnter color index to change all entities to: "
);
if (pr.Status == PromptStatus.OK)
{
short newColorIndex = (short)pr.Value;
ObjectId msId;
Transaction tr =
doc.TransactionManager.StartTransaction();
using (tr)
{
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
msId =
bt[BlockTableRecord.ModelSpace];
// Not needed, but quicker than aborting
tr.Commit();
}
int count =
ChangeNestedEntitiesToColor(msId, newColorIndex);
ed.Regen();
ed.WriteMessage(
"\nChanged {0} entit{1} to color {2}.",
count,
count == 1 ? "y" : "ies",
newColorIndex
);
}
}
private int ChangeNestedEntitiesToColor(
ObjectId btrId, short colorIndex)
{
int changedCount = 0;
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
Transaction tr =
doc.TransactionManager.StartTransaction();
using (tr)
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
btrId,
OpenMode.ForRead
);
foreach (ObjectId entId in btr)
{
Entity ent =
tr.GetObject(entId, OpenMode.ForRead)
as Entity;
if (ent != null)
{
BlockReference br = ent as BlockReference;
if (br != null)
{
// Recurse for nested blocks
changedCount +=
ChangeNestedEntitiesToColor(
br.BlockTableRecord,
colorIndex
);
}
else
{
if (ent.ColorIndex != colorIndex)
{
changedCount++;
// Entity is only open for read
ent.UpgradeOpen();
ent.ColorIndex = colorIndex;
ent.DowngradeOpen();
}
}
}
}
tr.Commit();
}
return changedCount;
}
}
}

Subscribe via RSS
Dear Kean
I´m working with .Net and Autocad. I´m trying to run a rutine that change the color of an object (line), I know how
to do this with one color, but i want to change the line in various colors, for example from red to green to yellow in intervals of time, the rutine must be run while i´m working
in the draw ( for example while i´m doing zoom ) but i need the line back to the original color when i do a click (event)
with the mouse. I can´t find the solution, can you help me ?!
Posted by: Claudio | June 28, 2007 at 05:30 AM
Dear Claudio,
It's certainly possible to set a timer and cycle through colours on a set of objects - the issue is doing so during a realtime pan/zoom and also accessing the database in a safe way irrespective of what is happening in the editor.
Frankly I'd look at leveraging the in-built selection highlighting mechanism inside AutoCAD, which would be much safer.
Regards,
Kean
Posted by: Kean | July 06, 2007 at 10:27 AM
Kean,
thanks for your info, but I am still stuck. I am using acad2006 - I have a folder full of small A3 drgs, each with a title block. I want to update the attributes of the Revision from A to B and insert "issued for construction" and the date etc. How can I do this using Global Attribute Editing techniques for Multiple drawings?
Cheers
TonyE
Posted by: Tony | October 31, 2007 at 07:38 AM
TonyE,
I suggest checking out this post.
Regards,
Kean
Posted by: Kean | October 31, 2007 at 09:59 AM
TonyE,
I suggest checking out this post.
Regards,
Kean
Posted by: Kean | October 31, 2007 at 10:00 AM