Here's an example using a named dictionary to store the 'watched polylines' identifiers.
The WatchedPolyline class
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using System;
using System.Linq;
using AcCoreAp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
namespace ObjectModifiedEventSample
{
class WatchedPolyline
{
static string dictName = "GILE_MODIFIED_EVENT";
static string xrecName => "WatchedPlines";
public static void Pline_Modified(object sender, EventArgs e)
{
var pline = (Polyline)sender;
AcCoreAp.ShowAlertDialog($"Area = {pline.Area}");
}
public static void AddPolyline(Transaction tr, Polyline pline)
{
var db = pline.Database;
var NOD = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
DBDictionary dict;
if (NOD.Contains(dictName))
{
dict = (DBDictionary)tr.GetObject(NOD.GetAt(dictName), OpenMode.ForRead);
}
else
{
tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite);
dict = new DBDictionary();
NOD.SetAt(dictName, dict);
tr.AddNewlyCreatedDBObject(dict, true);
}
Xrecord xrec;
ResultBuffer data;
if (dict.Contains(xrecName))
{
xrec = (Xrecord)tr.GetObject(dict.GetAt(xrecName), OpenMode.ForWrite);
data = xrec.Data;
if (!data.Cast<TypedValue>().Any(tv => tv.Value.Equals(pline.ObjectId)))
{
data.Add(new TypedValue(330, pline.ObjectId));
pline.Modified += Pline_Modified;
}
}
else
{
xrec = new Xrecord();
dict.SetAt(xrecName, xrec);
tr.AddNewlyCreatedDBObject(xrec, true);
data = new ResultBuffer(new TypedValue(330, pline.ObjectId));
pline.Modified += Pline_Modified;
}
xrec.Data = data;
}
public static void UpdatePolylines(Document doc)
{
var db = doc.Database;
using (doc.LockDocument())
using (var tr = db.TransactionManager.StartOpenCloseTransaction())
{
var NOD = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
if (NOD.Contains(dictName))
{
var dict = (DBDictionary)tr.GetObject(NOD.GetAt(dictName), OpenMode.ForRead);
if (dict.Contains(xrecName))
{
var xrec = (Xrecord)tr.GetObject(dict.GetAt(xrecName), OpenMode.ForWrite);
var data = new ResultBuffer();
foreach (TypedValue typedValue in xrec.Data)
{
var id = (ObjectId)typedValue.Value;
if (id.IsErased)
continue;
var pline = (Polyline)tr.GetObject(id, OpenMode.ForRead);
pline.Modified += Pline_Modified;
data.Add(typedValue);
}
xrec.Data = data;
}
}
tr.Commit();
}
}
}
}
The Initialization class
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using System;
using AcCoreAp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
namespace ObjectModifiedEventSample
{
public class Initialization : IExtensionApplication
{
public void Initialize()
{
AcCoreAp.Idle += OnIdle;
}
private void OnIdle(object sender, EventArgs e)
{
var docs = AcCoreAp.DocumentManager;
var acDoc = docs.MdiActiveDocument;
if (acDoc != null)
{
AcCoreAp.Idle -= OnIdle;
foreach (Document doc in docs)
{
WatchedPolyline.UpdatePolylines(doc);
}
docs.DocumentCreated += Docs_DocumentCreated;
}
}
public void Terminate()
{ }
private void Docs_DocumentCreated(object sender, DocumentCollectionEventArgs e) =>
WatchedPolyline.UpdatePolylines(e.Document);
}
}
The Commands class
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using AcCoreAp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
namespace ObjectModifiedEventSample
{
public class Commands
{
[CommandMethod("TEST")]
public static void Test()
{
var doc = AcCoreAp.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var options = new PromptEntityOptions("\nSelect Polyline: ");
options.SetRejectMessage("\nSelected object is not a Polyline.");
options.AddAllowedClass(typeof(Polyline), true);
var result = ed.GetEntity(options);
if (result.Status != PromptStatus.OK)
return;
using (var tr = db.TransactionManager.StartTransaction())
{
var pline = (Polyline)tr.GetObject(result.ObjectId, OpenMode.ForRead);
WatchedPolyline.AddPolyline(tr, pline);
tr.Commit();
}
}
}
}