Selecting a linetype and applying it to a set of AutoCAD entities using .NET

I received this request from Mateusz Andrzejczak, over the weekend:

I have problem with LineTypeDialog. Your part of the code is working perfectly, but i have problem with modifying the values. I have a SelectionSet that holds all object that are selected with using a filter. I want to use LineTypeDialog to select linetype and then accept so all the object in selection set will change to selected linetype. I'm working with this for a few hours and it's not working. Any tip for me?

The question related to this old post. I started by sending Mateusz a link to this follow-up post, which shows how to display various AutoCAD dialogs and then apply the chosen properties to a selected entity.

But then I thought about it, and decided to go ahead and implement Mateusz's request, showing a couple of additional "nice-to-have" features beyond just dealing with a selection set:

  1. Make sure the command works with the pickfirst selection set (so it can be called using the noun-verb interaction paradigm)
  2. Check the selection set to see whether the selected entities have the same linetype ID: if so, select that as the default in the dialog

Nothing really earth-shattering, but it does show the use of the linetype dialog in a somewhat more realistic scenario.

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;

 

namespace EntityProperties

{

  public class Commands

  {

    [CommandMethod("SLT", CommandFlags.UsePickSet)]

    public void SetLineType()

    {

      var doc = Application.DocumentManager.MdiActiveDocument;

      if (doc == null)

        return;

 

      var ed = doc.Editor;

 

      // Get the pickfirst selection set or ask the user to

      // select some entities

 

      var psr = ed.GetSelection();

      if (psr.Status != PromptStatus.OK || psr.Value.Count == 0)

        return;

 

      using (var tr = doc.TransactionManager.StartTransaction())

 

      {

        // Get the IDs of the selected objects

 

        var ids = psr.Value.GetObjectIds();

 

        // Loop through in read-only mode, checking whether the

        // selected entities have the same linetype

        // (if so, it'll be set in ltId, otherwise different will

        // be true)

 

        var ltId = ObjectId.Null;

        bool different = false;

 

        foreach (ObjectId id in ids)

        {

          // Get the entity for read

 

          var ent = (Entity)tr.GetObject(id, OpenMode.ForRead);

 

          // On the first iteration we store the linetype Id

 

          if (ltId == ObjectId.Null)

            ltId = ent.LinetypeId;

          else

          {

            // On subsequent iterations we check against the

            // first one and set different to be true if they're

            // not the same

 

            if (ltId != ent.LinetypeId)

       
60;    {

              different = true;

              break;

            }

          }

        }

 

        // Now we can display our linetype dialog with the common

        // linetype selected (if they have the same one)

 

        var ltd = new LinetypeDialog();

        if (!different)

          ltd.Linetype = ltId;

        var dr = ltd.ShowDialog();

        if (dr != System.Windows.Forms.DialogResult.OK)

          return; // We might also commit before returning

 

        // Assuming we have a different linetype selected

        // (or the entities in the selected have different

        // linetypes to start with) then we'll loop through

        // to set the new linetype

 

        if (different || ltId != ltd.Linetype)

        {

          foreach (ObjectId id in ids)

          {

            // This time we need write access

 

            var ent = (Entity)tr.GetObject(id, OpenMode.ForWrite);

 

            // Set the linetype if it's not the same

 

            if (ent.LinetypeId != ltd.Linetype)

              ent.LinetypeId = ltd.Linetype;

          }

        }

 

        // Finally we commit the transaction

 

        tr.Commit();

      }

    }

  }

}

When you run the SLT command, you'll see the linetype dialog has a default entry highlighted in the case where all the selected entities have the same linetype:

Selecting a linetype for a set of AutoCAD entities

Leave a Reply

Your email address will not be published. Required fields are marked *