Here's a question that came in to us, recently:
How can I show the AutoCAD color dialog from .NET? I need to allow the user to select a block, show the AutoCAD color dialog and apply the selected color to the contents of the selected block.
A new member of DevTech Americas - Augusto Gonçalves, who's based in our São Paulo office - answered with the following code (which I've modified slightly, mostly to follow this blog's coding conventions). Thanks, Augusto!
By the way, these previous posts may also be useful to those interested in this topic.
Here's the C# code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using Autodesk.AutoCAD.Colors;
namespace ColorPicking
{
public class Commands
{
[CommandMethod("CB")]
public void ColorBlock()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// Ask the user to select a block
PromptEntityOptions peo =
new PromptEntityOptions("\nSelect a block:");
peo.AllowNone = false;
peo.SetRejectMessage("\nMust select a block.");
peo.AddAllowedClass(typeof(BlockReference), false);
PromptEntityResult per =
ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
// Open the entity using a transaction
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
try
{
Entity ent =
(Entity)tr.GetObject(
per.ObjectId,
OpenMode.ForRead
);
// Should always be a block reference,
// but let's make sure
BlockReference br = ent as BlockReference;
if (br != null)
{
// Select the new color
ColorDialog cd = new ColorDialog();
cd.IncludeByBlockByLayer = true;
cd.ShowDialog();
// Change the color of the block itself
br.UpgradeOpen();
br.Color = cd.Color;
// Change every entity to be of color ByBlock
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
br.BlockTableRecord,
OpenMode.ForRead
);
// Iterate through the BlockTableRecord contents
foreach (ObjectId id in btr)
{
// Open the entity
Entity ent2 =
(Entity)tr.GetObject(id, OpenMode.ForWrite);
// Change each entity's color to ByBlock
ent2.Color =
Color.FromColorIndex(ColorMethod.ByBlock, 0);
}
}
// Commit if there hasn't been a problem
// (even if no objects changed: it's just quicker)
tr.Commit();
}
catch (Autodesk.AutoCAD.Runtime.Exception e)
{
// Something went wrong
ed.WriteMessage(e.ToString());
}
}
}
}
}
Here's a quick example of running the CB command on a block inserted from the "Architectural - Imperial" sample block library that ships with AutoCAD.
After launching the CB command selecting our sports car, we can see the colour selection dialog, which allows us to select an AutoCAD colour index, a true color or a standard colour from a color book:
We can then see our block is changed to this colour (well, in fact the block is changed to be this colour and all its contents are all changed to be coloured ByBlock):
This block happens to be a dynamic block, so if we change it to its truck representation, we see the colour has propagated there, also (as the geometry for this view also resides in the block table record, of course):
By the way, for those of you who are confused by my apparently inconsistent use of spelling, please see this previous post. :-)