Locking and unlocking AutoCAD layers visibly using .NET

On Friday I visited Munich Airport: not only to catch a flight home to Switzerland but also to take a look at some AutoCAD issues frustrating the developers working on the airport's facilities management system. During the course of the day we were able to work through a number of problems – such as using COM (SendCommand()) to run a script synchronously as well as to get the fill pattern for MPolygon objects (this is apparently broken in .NET) – but there was one I had to bring home with me: when locking and unlocking layers programmatically, their geometry doesn't fade and unfade despite LAYLOCKFADECTL being set correctly.

I found a few instances of this reported on the web, but I didn't come across a solution. After some work I found that if you set the IsOff property (or even IsFrozen, although I didn't actually try this) on the layer that's being locked/unlocked, then it's enough to trigger the layer change that can be picked up by Editor.ApplyCurDwgLayerTableChanges() (and then Editor.Regen()).

So yes, we're turning it off and on again. Sort of: we don't actually need to toggle IsOff – we can just set it to the current property value.

Here's the C# code implementing our LL (LockLayers) and UL (UnlockLayers) commands:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

 

namespace LayerManipulation

{

  public static class Extensions

  {

    public static void LockOrUnlockAllLayers(

      this Document doc, bool dolock, bool lockZero = false

    )

    {

      var db = doc.Database;

      var ed = doc.Editor;

 

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

      {

        var lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);

        foreach (var ltrId in lt)

        {

          // Don't try to lock/unlock either the current layer or layer 0

          // (depending on whether lockZero == true for the latter)

 

          if (ltrId != db.Clayer && (lockZero || ltrId != db.LayerZero))

          {

            // Open the layer for write and lock/unlock it

 

            var ltr = (LayerTableRecord)tr.GetObject(ltrId, OpenMode.ForWrite);

            ltr.IsLocked = dolock;

            ltr.IsOff = ltr.IsOff; // This is needed to force a graphics update

          }

        }

        tr.Commit();

      }

 

      // These two calls will result in the layer's geometry fading/unfading

      // appropriately

 

      ed.ApplyCurDwgLayerTableChanges();

      ed.Regen();

    }

  }

 

  public class Commands

  {

    [CommandMethod("LL")]

    public void LockLayers()

    {

      var doc = Application.DocumentManager.MdiActiveDocument;

      if (doc == null) return;

 

      doc.LockOrUnlockAllLayers(true);

    }

 

    [CommandMethod("UL")]

    public void UnlockLayers()

    {

      var doc = Application.DocumentManager.MdiActiveDocument;

      if (doc == null) return;

 

      doc.LockOrUnlockAllLayers(false);

    }

  }

}

 

Here we see the two commands in action:

Locking and unlocking layers

One response to “Locking and unlocking AutoCAD layers visibly using .NET”

  1. So do they make you go through the security check before you can help their autocad programmers?..."I don't actually have a plane ticket, I'm just going to help some .net buddies in the computer lab by terminal 22".... one way to get pulled aside.
    I'm kind of amazed an airport employs staff that program autocad, what are they doing that needs not only cad operators, but programmer level people there? (if you can say) thanks

    1. They're in an administration building before security. I asked if they could have someone drive me to my plane, but that apparently isn't a perk they enjoy. 🙂

      They had a mix of CAD programmers/administrators/support personnel apart from the various CAD & FM users.

      A very interesting visit!

      Kean

  2. Hi Kean

    I'm having the same issue when restoring a layerstate that contained locked layers. The lock is restored but the fade isn't. Is there a way to force the update in this situation or would I have to go into the layerstate, find the locked layers and then set the IsOff as you've demonstrated?

    Thanks

    1. Hi Paul,

      I don't know, off the top of my head. At the very least this approach should work, if you can't find a better way.

      Regards,

      Kean

  3. Hi Kean
    I am use cad 2012 not hvae Editor.ApplyCurDwgLayerTableChanges(),
    only Editor.Regen(), OK?
    Forgive my poor English

    Thanks

    1. I don't recall when that method was introduced. The main question is whether it works for you or not.

      Kean

      1. Use the Editor.Regen () method solves layer freeze, defrost switch refresh drawing problems.

        Thanks

  4. Jules Gabriel Pare Avatar
    Jules Gabriel Pare

    Thanks this is just what I needed, very odd that the regen alone doesn't do it. Appreciated.

Leave a Reply to Kean Walmsley Cancel reply

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