[CommandMethod("TransactionTesting")]
public void TestTransaction()
{
try
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
PromptEntityOptions peo
= new PromptEntityOptions
("\nSelect attribute to add"); peo.SetRejectMessage("\nNot an AttributeDefinition");
peo
.AddAllowedClass(typeof(AttributeDefinition
),
true); PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;
ObjectId adId = per.ObjectId;
peo
= new PromptEntityOptions
("\nSelect block to append attribute"); peo.SetRejectMessage("\nNot a BlockReference");
peo
.AddAllowedClass(typeof(BlockReference
),
true); per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;
ObjectId brId = per.ObjectId;
AttributeDefinition ad = null;
BlockReference br = null;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
try
{
AttributeDefinition ad1 = (AttributeDefinition)tr.GetObject(adId, OpenMode.ForWrite);
ad1.ObjectClosed += ad1_ObjectClosed;
BlockReference br1 = (BlockReference)tr.GetObject(brId, OpenMode.ForRead);
Application.ShowAlertDialog("Before Commit");
tr.Commit();
Application.ShowAlertDialog("After Commit");
ad = ad1;//will fail if disposed at tr.commit()
br = br1;
}
catch (System.Exception e)
{
ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
}
Application.ShowAlertDialog("Before Transaction Closed");
}
Application.ShowAlertDialog("After Transaction Closed");
ed.WriteMessage("\n" + ad.UnmanagedObject.ToString());
ed.WriteMessage("\n" + ad.IsDisposed.ToString());
ed.WriteMessage("\n" + ad.Tag);
//ad.LockPositionInBlock = true;///// Boom
using (Transaction tr = db.TransactionManager.StartTransaction())
{
try
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForWrite);
AttributeDefinition NEWad = (AttributeDefinition)ad.Clone();
NEWad.TransformBy(br.BlockTransform.Inverse()); //to set the AD to the BTR coordinate system
ObjectId NEWadId = btr.AppendEntity(NEWad);
tr.AddNewlyCreatedDBObject(NEWad, true);
ObjectIdCollection blockIds = btr.GetBlockReferenceIds(true, true);
if (!NEWad.Constant) //constant attributes are NOT added to the block reference
foreach (ObjectId id in blockIds) //add attribute reference to all blocks
{
br = (BlockReference)tr.GetObject(id, OpenMode.ForWrite);
AttributeReference ar
= new AttributeReference
(); ar.SetAttributeFromBlock(NEWad, br.BlockTransform);
ar.TextString = ad.TextString;
br.AttributeCollection.AppendAttribute(ar);
tr.AddNewlyCreatedDBObject(ar, true);
}
tr.GetObject(ad.ObjectId, OpenMode.ForWrite);//////Commit line out and Boom
ad.Erase();//////Will only work if above line is commented out
tr.Commit();
ed.Regen();//Regen needed for constant attribute to correctly display
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
if (ex.ErrorStatus != ErrorStatus.NotOpenForWrite)
{
ed.WriteMessage("\nError: {0}\n{1}", ex.GetBaseException(), ex.StackTrace);
}
throw;
}
}
BlockReference br2 = (BlockReference)br.Clone();//cloning outside of a transaction works
using (Transaction tr = db.TransactionManager.StartTransaction())
{
AttributeDefinition ad1
= new AttributeDefinition
(); ad1.SetDatabaseDefaults();
ad1.Tag = "tag";
ad1.TextString = "textString";
ad1.Constant = true;
Matrix3d mat = br2.BlockTransform;
ad1.TransformBy(mat);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
btr.AppendEntity(ad1);
tr.AddNewlyCreatedDBObject(ad1, true);
tr.Commit();
ed.Regen();
}
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage("\nError: {0}\n{1}", ex.GetBaseException(), ex.StackTrace);
}
}
void ad1_ObjectClosed(object sender, ObjectClosedEventArgs e)
{
Application.ShowAlertDialog("ObjectClosed");
}