Kean Walmsley

July 2009

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  

Twitter Updates

    follow me on Twitter



    « Testing whether an AutoCAD drawing is 2D or 3D using .NET | Main | Turtle fractals in AutoCAD using .NET - Part 4 »

    July 11, 2008

    Adding and removing AutoCAD layer filters using .NET

    This question came in by email last week:

    The last two days I am struggling with adding a new LayerGroup to HostApplicationServices.WorkingDatabase.LayerFilters.Root. I simply cannot get it working. Is it possible to write a blog item with example on this?

    An interesting question and it can indeed be quite tricky to understand how this works. For those of you who are ADN members, here's a DevNote covering the basics, which I've taken and extended for this post.

    When working with LayerFilters, it's important to know that the Database property providing access to the list of current LayerFilters does so by value (i.e. you have to get a copy of the current set of LayerFilters, manipulate it, and then set it back on the Database object to have them picked up by the system).

    The below C# code implements commands to list the existing layer filters (LLFS), create three new layer filters (CLFS), and delete a layer filter selected by the user (DLF):

    using Autodesk.AutoCAD.ApplicationServices;

    using Autodesk.AutoCAD.DatabaseServices;

    using Autodesk.AutoCAD.EditorInput;

    using Autodesk.AutoCAD.Runtime;

    using Autodesk.AutoCAD.LayerManager;


    namespace LayerFilters

    {

      public class Commands

      {

        [CommandMethod("LLFS")]

        static public void ListLayerFilters()

        {

          Document doc =

            Application.DocumentManager.MdiActiveDocument;

          Database db = doc.Database;

          Editor ed = doc.Editor;


          // List the nested layer filters


          LayerFilterCollection lfc =

            db.LayerFilters.Root.NestedFilters;


          for (int i = 0; i < lfc.Count; ++i)

          {

            LayerFilter lf = lfc[i];

            ed.WriteMessage(

              "\n{0} - {1} (can{2} be deleted)",

              i + 1,

              lf.Name,

              (lf.AllowDelete ? "" : "not")

            );

          }

        }


        [CommandMethod("CLFS")]

        static public void CreateLayerFilters()

        {

          Document doc =

            Application.DocumentManager.MdiActiveDocument;

          Database db = doc.Database;

          Editor ed = doc.Editor;


          try

          {

            // Get the existing layer filters

            // (we will add to them and set them back)


            LayerFilterTree lft =

              db.LayerFilters;

            LayerFilterCollection lfc =

              lft.Root.NestedFilters;


            // Create three new layer filters


            LayerFilter lf1 = new LayerFilter();

            lf1.Name = "Unlocked Layers";

            lf1.FilterExpression = "LOCKED==\"False\"";


            LayerFilter lf2 = new LayerFilter();

            lf2.Name = "White Layers";

            lf2.FilterExpression = "COLOR==\"7\"";


            LayerFilter lf3 = new LayerFilter();

            lf3.Name = "Visible Layers";

            lf3.FilterExpression =

              "OFF==\"False\" AND FROZEN==\"False\"";


            // Add them to the collection


            lfc.Add(lf1);

            lfc.Add(lf2);

            lfc.Add(lf3);


            // Set them back on the Database


            db.LayerFilters = lft;


            // List the layer filters, to see the new ones


            ListLayerFilters();

          }

          catch (Exception ex)

          {

            ed.WriteMessage(

              "\nException: {0}",

              ex.Message

            );

          }

        }


        [CommandMethod("DLF")]

        static public void DeleteLayerFilter()

        {

          Document doc =

            Application.DocumentManager.MdiActiveDocument;

          Database db = doc.Database;

          Editor ed = doc.Editor;


          ListLayerFilters();


          try

          {

            // Get the existing layer filters

            // (we will add to them and set them back)


            LayerFilterTree lft =

              db.LayerFilters;

            LayerFilterCollection lfc =

              lft.Root.NestedFilters;


            // Prompt for the index of the filter to delete


            PromptIntegerOptions pio =

              new PromptIntegerOptions(

              "\n\nEnter index of filter to delete"

              );

            pio.LowerLimit = 1;

            pio.UpperLimit = lfc.Count;


            PromptIntegerResult pir =

              ed.GetInteger(pio);


            // Get the selected filter


            LayerFilter lf = lfc[pir.Value - 1];


            // If it's possible to delete it, do so


            if (!lf.AllowDelete)

            {

              ed.WriteMessage(

                "\nLayer filter cannot be deleted."

              );

            }

            else

            {

              lfc.Remove(lf);

              db.LayerFilters = lft;


              ListLayerFilters();

            }

          }

          catch(Exception ex)

          {

            ed.WriteMessage(

              "\nException: {0}",

              ex.Message

            );

          }

        }

      }

    }

    Here's what happens when we run the various commands:

    Command: LLFS


    1 - All Used Layers (cannot be deleted)

    2 - Unreconciled New Layers (cannot be deleted)

    3 - Viewport Overrides (cannot be deleted)


    Command: CLFS


    1 - Unlocked Layers (can be deleted)

    2 - White Layers (can be deleted)

    3 - Visible Layers (can be deleted)

    4 - All Used Layers (cannot be deleted)

    5 - Unreconciled New Layers (cannot be deleted)

    6 - Viewport Overrides (cannot be deleted)


    Command: DLF


    1 - Unlocked Layers (can be deleted)

    2 - White Layers (can be deleted)

    3 - Visible Layers (can be deleted)

    4 - All Used Layers (cannot be deleted)

    5 - Unreconciled New Layers (cannot be deleted)

    6 - Viewport Overrides (cannot be deleted)


    Enter index of filter to delete: 1


    1 - White Layers (can be deleted)

    2 - Visible Layers (can be deleted)

    3 - All Used Layers (cannot be deleted)

    4 - Unreconciled New Layers (cannot be deleted)

    5 - Viewport Overrides (cannot be deleted)

    You can see the three new filters (before you delete any with the DLF command) in the LAYER dialog. To see them work, create a bunch of layers, changing the colour of some and turning off/freezing/locking others:

    Layer Filters

    TrackBack

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

    Listed below are links to weblogs that reference Adding and removing AutoCAD layer filters using .NET:

    Comments

    Hallo Kean,

    Thank you for that great posting, but I've one more question to this topic:
    Is it possible to set a layerfilter activ using .NET API?

    thanks in advance,
    Patrick

    Hi Patrick,

    I don't believe so. The ADN team, or someone on the discussion groups, may know differently, though.

    Regards,

    Kean

    Kean,
    You entries have been great with helping me get started with Acad Programming. Your example above shows how to create a property type filter, how do you add layers to a group type filter (LayerGroup class)? I can create the group filter but can't figure out how to add layers to the group. The filterexpression method is available but doesn't seem to work (at least not like with the LayerFilter object)

    i.e.
    Dim lyrGrp As New LayerGroup
    Dim lyrFltr As New LayerFilter
    lyrFltr.FilterExpression = "NAME==""LayerName""" 'works
    lyrGrp.FilterExpression = "NAME==""LayerName""" 'does not work

    Thanks,
    Mike

    Mike,

    Check the blog tomorrow for a post detailing how to do this.

    Thanks for the question!

    Kean

    Hi Kean,

    I've trying to set a layerFilter active.
    Using the name property of the Root/Current only renames the current one. And because the Root and Current are readonly you can't set a object to it (LayerFilter), But the new method accepts a Root and current LayerFilter objects, I've tried it and it does the trick.

    Michel

    Great - thanks, Michel!

    Kean

    Hi,

    Well, spoke to soon.
    The LayerFilter needs to be accessed once thruw the layermanager. (per drawing). After this the "new method" works. ??


    Michel

    Hi Kean,

    Very good post. I have a question.In DeleteLayerFilter instead of reading index to be filtered is it possible to read layername and delete

    I don't know of a reason why that wouldn't work. You would either need to index into the LayerFilterCollection via a string or - if that's not possible - iterate through the LayerFilters and check for one with the Name you're after before deleting it.

    Kean

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search