December 2014

Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      










« Free AutoCAD programming webcast: .NET for LISP Programmers | Main | Offline reading of "Through the Interface" »

October 15, 2008

Changing the colour of the contents of an AutoCAD block using .NET

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:

Select color for block contents

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):

Purple sports car

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):

Purple truck

By the way, for those of you who are confused by my apparently inconsistent use of spelling, please see this previous post. :-)

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83452464869e20105358442e3970c

Listed below are links to weblogs that reference Changing the colour of the contents of an AutoCAD block using .NET:

blog comments powered by Disqus

Feed/Share

10 Random Posts