In the last few posts on this topic, we saw some examples of getting information from and controlling AutoCAD via its Bindable Object Layer.
In this post, we’re going to look at a way to find out when changes are made to AutoCAD’s layer table: when layers are added, changed or removed.
There are certainly other ways to do this: you can use Database.ObjectAppended(), ObjectModified() and ObjectErased() to find out about changes to LayerTableRecords, for instance, but this is an alternative approach that may be interesting to some people.
In this implementation, we attach some event handlers to keep an eye on what’s happening in the BOL collection bound to the layer table. We also maintain a list of layer names so we have good information on what has changed (in terms of what layers have been removed, at least – if we wanted information on specific changes we’d need to cache more information than that). From this starting point, it should be possible for developers to get a more comprehensive mechanism that provides information on when commands create or remove multiple layers (something this particular implementation hasn’t specifically been designed to deal with or tested against).
Here’s the C# code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows.Data;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.ComponentModel;
public class BolInfo
{
static private List<string> _layerNames = null;
[CommandMethod("LAYMODS")]
static public void GetNotifiedOnLayerChange()
{
// Get our layer list and extract the initial layer names
var layers = Application.UIBindings.Collections.Layers;
UpdateStoredLayerNames();
// Attach event handlers to the layer list...
// Find out when items are added or removed from the
// collection
layers.CollectionChanged +=
(s, e) =>
{
Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\nCollection changed: {0}", e.Action);
if (
e.Action == NotifyCollectionChangedAction.Add &&
e.NewStartingIndex == -1
)
{
// What happens for commands that create >1 layers?
var newLays = Application.UIBindings.Collections.Layers;
ed.WriteMessage(
"\nNew item: \"{0}\"",
GetItemValue(newLays[newLays.Count - 1])
);
}
else if (
e.Action == NotifyCollectionChangedAction.Remove
)
{
ed.WriteMessage(
"\nRemoved item: \"{0}\"",
_layerNames[e.OldStartingIndex]
);
}
// As we can't access data in e.NewItems or e.OldItems
// (they contain NewDataItem objects - a class that isn't
// exposed) get the collection again and list it
ed.WriteMessage("\nUpdated collection: ");
foreach (
var item in Application.UIBindings.Collections.Layers
)
{
ed.WriteMessage(" \"{0}\"", GetItemValue(item));
}
UpdateStoredLayerNames();
};
// Find out when items have been changed in the collection
// (although not what specifically has changed)
layers.ItemsChanged +=
(s, e) =>
{
Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\nItem(s) changed.");
UpdateStoredLayerNames();
};
// Find out when properties of the collection (typically
// the Count, for instance) have changed
layers.PropertyChanged +=
(s, e) =>
{
Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage(
"\nCollection property changed: {0}", e.PropertyName
);
};
}
// Store a cache of the layer names
private static void UpdateStoredLayerNames()
{
var layers = Application.UIBindings.Collections.Layers;
_layerNames = new List<string>(layers.Count);
foreach (var layer in layers)
{
_layerNames.Add(GetItemValue(layer));
}
}
// Extract the name of an item from the item descriptor
private static string GetItemValue(ICustomTypeDescriptor item)
{
return (string)item.GetProperties()["Name"].GetValue(item);
}
}
When we run the custom LAYMODS command and then use the standard LAYER command to add, change and remove some layers, we can see the level of information provided:
Command: LAYMODS
Command: LAYER
Command:
Command:
Collection changed: Add
New item: "Layer1"
Updated collection: "0" "Layer1"
Collection property changed: Count
Command:
Collection changed: Add
New item: "Layer2"
Updated collection: "0" "Layer1" "Layer2"
Collection property changed: Count
Command:
Collection changed: Add
New item: "Layer3"
Updated collection: "0" "Layer1" "Layer2" "Layer3"
Collection property changed: Count
Command:
Collection changed: Add
New item: "Layer4"
Updated collection: "0" "Layer1" "Layer2" "Layer3" "Layer4"
Collection property changed: Count
Command:
Collection changed: Add
New item: "Layer5"
Updated collection: "0" "Layer1" "Layer2" "Layer3" "Layer4" "Layer5"
Collection property changed: Count
Command:
Command:
Collection changed: Add
New item: "Layer7"
Updated collection: "0" "Layer1" "Layer2" "Layer3" "Layer4" "Layer5" "Layer6" "Layer7"
Collection property changed: Count
Command:
Collection changed: Add
New item: "Layer8"
Updated collection: "0" "Layer1" "Layer2" "Layer3" "Layer4" "Layer5" "Layer6" "Layer7" "Layer8"
Collection property changed: Count
Command:
Collection changed: Remove
Removed item: "Layer3"
Updated collection: "0" "Layer1" "Layer2" "Layer4" "Layer5" "Layer6" "Layer7" "Layer8"
Collection property changed: Count
Command:
Collection changed: Remove
Removed item: "Layer4"
Updated collection: "0" "Layer1" "Layer2" "Layer5" "Layer6" "Layer7" "Layer8"
Collection property changed: Count
Command:
Collection changed: Remove
Removed item: "Layer5"
Updated collection: "0" "Layer1" "Layer2" "Layer6" "Layer7" "Layer8"
Collection property changed: Count
Command:
Collection changed: Remove
Removed item: "Layer6"
Updated collection: "0" "Layer1" "Layer2" "Layer7" "Layer8"
Collection property changed: Count
Command:
Item(s) changed.
Command:
Item(s) changed.
Command:
Command:
Collection changed: Add
New item: "Layer4"
Updated collection: "0" "Layer1" "Layer2" "Layer7" "Layer8" "Layer3" "Layer4"
Collection property changed: Count
Command:
Collection changed: Add
New item: "Layer5"
Updated collection: "0" "Layer1" "Layer2" "Layer7" "Layer8" "Layer3" "Layer4" "Layer5"
Collection property changed: Count
Command:
Collection changed: Add
New item: "Layer6"
Updated collection: "0" "Layer1" "Layer2" "Layer7" "Layer8" "Layer3" "Layer4" "Layer5" "Layer6"
Collection property changed: Count