简单实现AutoCAD Undo操作

在命令行输入"UNDO",会看到"Enter the number of operations to undo or [Auto/Control/BEgin/End/Mark/Back]",本文就利用"BEgin/End/Mark/Back”在ARX开发中实现Undo的操作。

1. Undo 操作的结构:
_BEgin
_Mark
_Undo
_End

2. 注意事项:

一组{_BEgin, _End}为一个操作单元,其内部不能再嵌套另一个{_BEgin, _End}。

{_BEgin, _End}不能嵌在任何Transaction内部,但其内部可以嵌任意多个Transaction.

最好一个_Mark标识一个Transaction.

using System; using System.Collections.Generic; using System.Text; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.GraphicsInterface; using Autodesk.AutoCAD.Runtime; using ArxApp = Autodesk.AutoCAD.ApplicationServices.Application; using ObjectArxNet.Commons; namespace ObjectArxNet.Test { public class Undo { [CommandMethod("My_Undo")] public void InitCommand() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; try { //Filter the correct entity which you want. Using SelectionAdded to replace the SelectionFilter. ed.SelectionAdded += new SelectionAddedEventHandler(callback_SelectionAdded); //Selection Filter //TypedValue[] filList = //{ // new TypedValue((int)DxfCode.Operator, "<and"), // new TypedValue((int)DxfCode.Start, "LWPolyLine"), // new TypedValue((int)DxfCode.Operator, "and>"), // new TypedValue((int)DxfCode.Operator, "<not"), // new TypedValue((int)DxfCode.LinetypeName, Consts.CONTINUOUS), // new TypedValue((int)DxfCode.Operator, "not>"), // new TypedValue((int)DxfCode.Operator, "<not"), // new TypedValue((int)DxfCode.LinetypeName, Consts.BYBLOCK), // new TypedValue((int)DxfCode.Operator, "not>"), //}; //SelectionFilter filter = new SelectionFilter(filList); //Use pick first PromptSelectionResult selectionRes = ed.SelectImplied(); bool usePickfirst = false; if (selectionRes.Status == PromptStatus.OK) { // If there was a pickfirst set, clear it ed.SetImpliedSelection(new ObjectId[0]); ObjectId[] objIds = selectionRes.Value.GetObjectIds(); if (objIds != null) { usePickfirst = objIds.Length > 0; } } //Selection Options PromptSelectionOptions selOpt = new PromptSelectionOptions(); selOpt.MessageForAdding = Consts.KEY_SELECT; selOpt.MessageForRemoval = Consts.KEY_SELECT; //Keyword Options PromptKeywordOptions optManual = new PromptKeywordOptions("/nSelect aligning mode"); optManual.Keywords.Add(Consts.KEY_AUTO_SELECT, Consts.KEY_AUTO_SELECT, Consts.KEY_AUTO_SELECT_DIS); optManual.Keywords.Add(Consts.KEY_INSERT, Consts.KEY_INSERT, Consts.KEY_INSERT_DIS); optManual.Keywords.Add(Consts.KEY_UNDO, Consts.KEY_UNDO, Consts.KEY_UNDO); optManual.Keywords.Add(Consts.KEY_EXIT, Consts.KEY_EXIT, Consts.KEY_EXIT); optManual.AllowNone = false; optManual.Keywords.Default = Consts.KEY_AUTO_SELECT; PromptResult res = null; if (usePickfirst) { Tools.RunCommand("_.UNDO", "_BEgin"); res = ed.GetKeywords(optManual); } else { Tools.RunCommand("_.UNDO", "_BEgin"); PromptSelectionResult selRes = ed.GetSelection(selOpt); //, filter if (selRes.Status == PromptStatus.OK) { ObjectId[] objIds = selRes.Value.GetObjectIds(); if (objIds != null) { res = ed.GetKeywords(optManual); } } } while (res != null && res.Status == PromptStatus.OK) { switch (res.StringResult) { case Consts.KEY_AUTO_SELECT: { Tools.RunCommand("_.UNDO", "_Mark"); Tools.WriteLine(string.Format("DO: {0}", Consts.KEY_AUTO_SELECT)); res = ed.GetKeywords(optManual); break; } case Consts.KEY_INSERT: { Tools.RunCommand("_.UNDO", "_Mark"); Tools.WriteLine(string.Format("DO: {0}", Consts.KEY_INSERT)); res = ed.GetKeywords(optManual); break; } case Consts.KEY_REMOVE: { Tools.RunCommand("_.UNDO", "_Mark"); Tools.WriteLine(string.Format("DO: {0}", Consts.KEY_REMOVE)); res = ed.GetKeywords(optManual); break; } case Consts.KEY_UNDO: { Tools.RunCommand("_.UNDO", "_Back"); Tools.WriteLine(string.Format("DO: {0}", Consts.KEY_UNDO)); doc.TransactionManager.QueueForGraphicsFlush(); res = ed.GetKeywords(optManual); break; } case Consts.KEY_EXIT: { Tools.RunCommand("_.UNDO", "_End");//end the last Tools.WriteLine(string.Format("DO: {0}", Consts.KEY_EXIT)); doc.TransactionManager.QueueForGraphicsFlush(); Tools.RunCommand("_.UNDO", "_BEgin");//begin the next PromptSelectionResult selRes = ed.GetSelection(selOpt); //, filter if (selRes.Status == PromptStatus.OK) { ObjectId[] objIds = selRes.Value.GetObjectIds(); if (objIds != null) { res = ed.GetKeywords(optManual); } } else { return; } break; } default: { doc.TransactionManager.QueueForGraphicsFlush(); res = ed.GetKeywords(optManual); break; } } } } finally { Tools.RunCommand("_.UNDO", "_End"); ed.SelectionAdded -= new SelectionAddedEventHandler(callback_SelectionAdded); } } private void callback_SelectionAdded(object sender, SelectionAddedEventArgs e) { try { if (e.AddedObjects.Count > 0) { ObjectId[] selIds = e.AddedObjects.GetObjectIds(); using (Transaction tr = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction()) { int index = 0; foreach (ObjectId id in selIds) { if (IsContinuous(id)) { e.Remove(index); } index++; } } } } catch (System.Exception) { } } private bool IsContinuous(ObjectId id) { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; bool result = false; using (Transaction tr = db.TransactionManager.StartTransaction()) { Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity; if (ent != null) { if ((string.Compare(ent.Linetype, "CONTINUOUS", true) == 0) || (string.Compare(ent.Linetype, "BYBLOCK", true) == 0)) { result = true; } if (string.Compare(ent.Linetype, "BYLAYER", true) == 0) { LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(ent.LayerId, OpenMode.ForRead); LinetypeTableRecord linetypeRec = (LinetypeTableRecord)tr.GetObject(ltr.LinetypeObjectId, OpenMode.ForRead); if (string.Compare(linetypeRec.Name, "CONTINUOUS", true) == 0) { result = true; } } } tr.Commit(); } return result; } internal class Consts { public const double ZERO = 1.0e-6; //Key worlds group 1 public const string KEY_SELECT = "Select polyline or [select ALL]"; //Key worlds group 2 public const string KEY_AUTO_SELECT = "Automatic"; public const string KEY_AUTO_SELECT_DIS = "Automatic"; public const string KEY_INSERT = "Manual"; public const string KEY_INSERT_DIS = "Manual"; public const string KEY_REVERSE = "Reverse"; public const string KEY_REVERSE_DIS = "Reverse direction"; public const string KEY_REMOVE = "rEmove"; public const string KEY_REMOVE_DIS = "rEmove redundant"; public const string KEY_UNDO = "Undo"; public const string KEY_EXIT = "eXit"; public const string CONTINUOUS = "CONTINUOUS"; public const string BYBLOCK = "BYBLOCK"; public const string BYLAYER = "BYLAYER"; public const string OSMODE = "OSMODE"; } } }

你可能感兴趣的:(简单实现AutoCAD Undo操作)