public static string disclaimer = " AutoCAD. – .";
using System; using Autodesk.AutoCAD.Runtime; using Autodesk.Windows; namespace MyAutoCADDll { public class Commands : IExtensionApplication { // AutoCAD "TestCommand" [CommandMethod("TestCommand")] public void MyCommand() { } // Initialize() Terminate() , IExtensionApplication public void Initialize() { } public void Terminate() { } } }
CopyLocal
). using System; using System.IO; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; namespace HabrPlug_Layers { public class Commands : IExtensionApplication { // AutoCAD "TestCommand" [CommandMethod("TestCommand")] public void MyCommand() { // Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // using (DocumentLock docloc = acDoc.LockDocument()) { // using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) { // LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable; // LayerTableRecord acLyrTblRec = new LayerTableRecord(); acLyrTblRec.Name = "HabrLayer"; // acLyrTbl.Add(acLyrTblRec); // tr.AddNewlyCreatedDBObject(acLyrTblRec, true); // tr.Commit(); } } } // Initialize() Terminate() , IExtensionApplication public void Initialize() { } public void Terminate() { } } }
using (DocumentLock docloc = acDoc.LockDocument())
DocumentLock
object's Dispose()
method. You can also use a using
block with declaring a DocumentLock
object in it - in this case, when you exit the block, the database is unlocked automatically. ( source , mirror )Dispose()
method to zero. using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) … tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable; … tr.AddNewlyCreatedDBObject(acLyrTblRec, true); … tr.Commit();
DocumentLock
, you must either call the Dispose()
method after you finish working with a transaction, or use the using construct.Autodesk.AutoCAD.Runtime
- to use the IExtensionApplication
type and the CommandMethod
construction;Autodesk.AutoCAD.DatabaseServices
- to use the Document
and DocumentLock
types;Autodesk.AutoCAD.Runtime
- to use the Database
, Transaction
, LayerTable
, OpenMode
and LayerTableRecord
. // Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // using (DocumentLock docloc = acDoc.LockDocument()) { // using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) {
LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable;
GetObject()
method takes as input two parameters: the Id of the object to be opened and the access level. You can find the Id of the document's layers table using the LayerTableId
property of the database of this document. Since we need to change the layer table (add a new layer to it), we use the write access level ( OpenMode.ForWrite
). Finally, the GetObject()
method returns a value of type “object” ( object
), which must be explicitly cast to the type we need ( LayerTable
). LayerTableRecord acLyrTblRec = new LayerTableRecord(); acLyrTblRec.Name = "HabrLayer";
LayerTableRecord
. Its constructor takes no values, so all initialization has to be done after creation.IsOff
property) or accessibility for editing ( IsLocked
property). acLyrTbl.Add(acLyrTblRec);
IEnumerable
interface is implemented. To add a new element, use the Add()
method. tr.AddNewlyCreatedDBObject(acLyrTblRec, true);
AddNewlyCreatedDBObject
function should not be called before, but after adding a layer to the table of document layers. If you try to swap these operations, the layer will not be added. I have no coherent logical explanation for this; I will be glad if knowledgeable people will share a clue in the comments. tr.Commit();
GetObject()
method GetObject()
been changed, then to save these changes in the document database, you need to commit the transaction by calling the Commit()
method. Otherwise, no changes will be saved, and the document will remain in the state that existed at the time of the start of the transaction. } }
Dispose()
method, especially since you need to do it twice - to commit the transaction and unlock the document. And when using the using construct, the Dispose()
method is called automatically.Clayer
property of the Clayer
database. acCurDb .Clayer = acLyrTbl["HabrLayer"];
using System; using System.IO; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; namespace HabrPlug_Layers { public class Commands : IExtensionApplication { // AutoCAD "TestCommand" [CommandMethod("TestCommand")] public void MyCommand() { // Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // using (DocumentLock docloc = acDoc.LockDocument()) { // using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) { // LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable; // LayerTableRecord acLyrTblRec = new LayerTableRecord(); acLyrTblRec.Name = "HabrLayer"; // acLyrTbl.Add(acLyrTblRec); // tr.AddNewlyCreatedDBObject(acLyrTblRec, true); // tr.Commit(); } } } // AutoCAD "NewCommand" [CommandMethod("NewCommand")] public void NewCommand() { // Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // using (DocumentLock docloc = acDoc.LockDocument()) { // using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) { // LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable; // - if (acLyrTbl.Has("HabrLayer") == false) { return; } // LayerTableRecord acLyrTblRec = tr.GetObject(acLyrTbl["HabrLayer"], OpenMode.ForWrite) as LayerTableRecord; // acLyrTblRec.Name = "test"; acLyrTblRec.IsOff = true; acLyrTblRec.IsLocked = true; // tr.Commit(); } } } // Initialize() Terminate() , IExtensionApplication public void Initialize() { } public void Terminate() { } } }
Has()
method of the document's layer table.Erase()
method is called as follows: acLyrTblRec.Erase(true);
try ... catch
construction. using System; using System.IO; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; namespace HabrPlug_Layers { public class Commands : IExtensionApplication { // AutoCAD "TestCommand" [CommandMethod("TestCommand")] public void MyCommand() { // Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // using (DocumentLock docloc = acDoc.LockDocument()) { // using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) { // LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable; // LayerTableRecord acLyrTblRec = new LayerTableRecord(); acLyrTblRec.Name = "HabrLayer"; // acLyrTbl.Add(acLyrTblRec); // tr.AddNewlyCreatedDBObject(acLyrTblRec, true); // tr.Commit(); } } } // AutoCAD "TestCommand" [CommandMethod("NewCommand")] public void NewCommand() { // Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // using (DocumentLock docloc = acDoc.LockDocument()) { // using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) { // LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable; // - if (acLyrTbl.Has("HabrLayer") == false) { return; } // acCurDb.Clayer = acLyrTbl["0"]; // , ObjectIdCollection acObjIdColl = new ObjectIdCollection(); acObjIdColl.Add(acLyrTbl["HabrLayer"]); acCurDb.Purge(acObjIdColl); if (acObjIdColl.Count > 0) { // LayerTableRecord acLyrTblRec = tr.GetObject(acObjIdColl[0], OpenMode.ForWrite) as LayerTableRecord; try { // acLyrTblRec.Erase(true); // tr.Commit(); } catch (Autodesk.AutoCAD.Runtime.Exception Ex) { // - , Application.ShowAlertDialog(":\n" + Ex.Message); } } } } } // Initialize() Terminate() , IExtensionApplication public void Initialize() { } public void Terminate() { } } }
Purge()
method. The principle of its operation is described in the documentation : it analyzes the collection of objects and, at its output, leaves only those objects to which no one refers.Purge()
method is called for a collection in which there is only one object — the layer to be deleted. If no one references this layer, then after calling the Purge()
method, it will remain in the collection, and then you can proceed to delete. If the call to the Purge()
method returns an empty collection, then there are references to the layer to be removed - probably, the objects placed on it.SetSystemVariable
function: Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("LAYLOCKFADECTL", 0);
using System; using System.IO; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; namespace HabrPlug_Layers { public class Commands : IExtensionApplication { // int old_LAYLOCKFADECTL = 0; // public void Initialize() { // old_LAYLOCKFADECTL = System.Convert.ToInt32(Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("LAYLOCKFADECTL")); // 0 Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("LAYLOCKFADECTL", 0); } // AutoCAD public void Terminate() { // , Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("LAYLOCKFADECTL", old_LAYLOCKFADECTL); } } }
Terminate()
does not always work correctly, and the original value may not be restored. But at least we tried.)Source: https://habr.com/ru/post/249015/
All Articles