Out of curiousity I decided to try implementing the ObjectOverrule you very kindly shared and, having added the following code inside of my Initialize() method:
static AttributeReferenceOverrule _attributeReferenceOverrule = null;
public void Initialize()
{
Document dwg = Application.DocumentManager.MdiActiveDocument;
ed = dwg.Editor;
try
{
ed.WriteMessage("\nInitializing {0}...", this.GetType().Name);
if (_attributeReferenceOverrule == null)
{
_attributeReferenceOverrule = new AttributeReferenceOverrule();
ObjectOverrule.AddOverrule(RXObject.GetClass(typeof(AttributeReference)), _attributeReferenceOverrule, true);
ObjectOverrule.Overruling = true;
ed.WriteMessage("\nAttributeReferenceOverrule added.");
}
}
catch (System.Exception ex)
{
ed.WriteMessage("failed:\n{0}", ex.ToString());
}
}
and the following to Terminate():
public void Terminate()
{
if (_attributeReferenceOverrule != null)
{
ObjectOverrule.RemoveOverrule(RXObject.GetClass(typeof(AttributeReference)), _attributeReferenceOverrule);
_attributeReferenceOverrule.Dispose();
_attributeReferenceOverrule = null;
ed.WriteMessage("\nAttributeReferenceOverrule removed.");
}
}
For completeness here is my (slightly) modified ObjectOverrule:
public class AttributeReferenceOverrule : ObjectOverrule
{
static RXClass rxclass = RXObject.GetClass(typeof(AttributeReference));
public AttributeReferenceOverrule()
{
AddOverrule(rxclass, this, true);
}
public override DBObject DeepClone(DBObject dbObject, DBObject ownerObject, IdMapping idMap, bool isPrimary)
{
var result = base.DeepClone(dbObject, ownerObject, idMap, isPrimary);
AttributeReference copy = result as AttributeReference;
if (copy != null)
{
/// TODO: Use additional conditions to decide if this
/// AttributeReference's TextString should be cleared,
/// which could involve any or all of the arguments to
/// this method.
/// In this example, the TextString is cleared unconditionally:
if (!copy.IsWriteEnabled)
copy.UpgradeOpen();
if (copy.Tag == "NearestCornerBlockName" || copy.Tag == "BlockNumber")
{
copy.TextString = string.Empty;
}
}
return result;
}
protected override void Dispose(bool disposing)
{
RemoveOverrule(rxclass, this);
base.Dispose(disposing);
}
}
And it does indeed offer a near-seamless approach to zeroing out specific attributereferences if a block reference is copied and it contains one of the tags listed.
However, I notice that one side-effect (once the Overrule code has loaded) is that none of my CommandMethods are recognised by AutoCAD. If I subsequently close AutoCAD and uncomment the other method I had chosen to use, everything works as-expected.
Is there something obvious I am missing to do with the ObjectOverrule?