namespace Namespace1
{
public static class Commands
{
/// Example: Sub-command undo
///
/// This is the simplest way to implement
/// individually-undoable steps within a
/// command that repetitively prompts for
/// input and creates geometry immediately
/// after each input request.
[CommandMethod( "SUBUNDOEXAMPLE" )]
public static void UndoGroupExample()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
ObjectId ms = SymbolUtilityServices.GetBlockModelSpaceId( db );
PromptPointOptions ppo
= new PromptPointOptions
( "\nPick center point: " ); ppo.AllowNone = true; // allow exit via ENTER
ppo.Keywords.Add( "Undo" );
Keyword undoKeyword = ppo.Keywords[0];
var transmgr = doc.TransactionManager;
Stack
<Entity
> circles
= new Stack
<Entity
>(); using( Transaction outer = transmgr.StartTransaction() )
{
transmgr.EnableGraphicsFlush( true );
while( true )
{
undoKeyword.Enabled = circles.Count > 0;
PromptPointResult ppr = doc.Editor.GetPoint( ppo );
switch( ppr.Status )
{
case PromptStatus.Cancel: // ESC exit roll back everything
return;
case PromptStatus.None: // ENTER exit and commit changes
outer.Commit();
return;
case PromptStatus.Keyword: // Undo the last circle
if( circles.Count > 0 )
{
UpdateDisplay( () => circles.Pop().Erase() ); // see below
}
else
doc.Editor.WriteMessage( "\nNothing to undo" );
continue;
}
if( ppr.Status != PromptStatus.OK )
throw new InvalidOperationException
( "Unexpected result" ); using( Transaction tr = transmgr.StartTransaction() )
{
BlockTableRecord model = (BlockTableRecord)
tr.GetObject( ms, OpenMode.ForWrite ) as BlockTableRecord;
Circle circle
= new Circle
( ppr
.Value, Vector3d
.ZAxis,
1.0 ); try
{
circle.SetDatabaseDefaults( db );
model.AppendEntity( circle );
}
catch
{
circle.Dispose();
throw;
}
transmgr.AddNewlyCreatedDBObject( circle, true );
circles.Push( circle );
transmgr.QueueForGraphicsFlush();
tr.Commit();
doc.Editor.UpdateScreen();
}
}
}
}
/// Helper:
///
/// Executes caller-supplied delegate within a
/// transaction and updates the display:
public static void UpdateDisplay( Action action )
{
Document doc = Application.DocumentManager.MdiActiveDocument;
if( doc == null )
throw new InvalidOperationException
( "no document" ); var transmgr = doc.TransactionManager;
transmgr.EnableGraphicsFlush( true );
using( Transaction tr = transmgr.StartTransaction() )
{
action();
transmgr.QueueForGraphicsFlush();
tr.Commit();
doc.Editor.UpdateScreen();
}
}
}
}