Once an object is opened using either the GetObject or Open methods, you can change the current open mode of an object with the UpgradeOpen and DowngradeOpen methods. The UpgradeOpen method changes an object open for read to write mode, while DowngradeOpen changes an object open for write to read mode. You do not need to pair a call to DowngradeOpen with each UpgradeOpen call, since closing of an object or disposing of a transaction will sufficiently cleanup the open state of an entity.
When you go to open an object, open the object in the mode that you will use the object in. Do not just open an object for write when you might only need to query an object. It is more efficient to open an object for read and query the object’s properties than it is to open the object for write and query the object’s properties.
Opening an object for write causes undo filing to start for the object. Undo filing is used to track changes to an object, so any changes made can be rolled back. If you are uncertain if you need to modify an object, it is best to open an object for read and then upgrade it for write. This will help to reduce the overhead of your program.
An example of when you might use UpgradeOpen is when you might be querying objects to see if they match a specific condition, and if the condition is met then you would upgrade the object from read to write mode to make modifications to it.
Similarly, if an object is open for notify and you receive a notification, you use UpgradeFromNotify to upgrade the object for write. Then you would use DowngradeToNotify to downgrade the object back to notify. UpgradeFromNotify and DowngradeFromNotify are reserved for use in methods that are intended to be used by an object to change its own open status so that it can safely modify itself.
Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices <CommandMethod("FreezeDoorLayer")> _ Public Sub FreezeDoorLayer() '' Get the current document and database Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim acCurDb As Database = acDoc.Database '' Start a transaction Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() '' Open the Layer table for read Dim acLyrTbl As LayerTable acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead) '' Step through each layer and update those that start with 'Door' For Each acObjId As ObjectId In acLyrTbl '' Open the Layer table record for read Dim acLyrTblRec As LayerTableRecord acLyrTblRec = acTrans.GetObject(acObjId, OpenMode.ForRead) '' Check to see if the layer's name starts with 'Door' If (acLyrTblRec.Name.StartsWith("Door", _ StringComparison.OrdinalIgnoreCase) = True) Then '' Check to see if the layer is current, if so then do not freeze it If acLyrTblRec.ObjectId <> acCurDb.Clayer Then '' Change from read to write mode acLyrTblRec.UpgradeOpen() '' Freeze the layer acLyrTblRec.IsFrozen = True End If End If Next '' Commit the changes and dispose of the transaction acTrans.Commit() End Using End Sub
using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; [CommandMethod("FreezeDoorLayer")] public static void FreezeDoorLayer() { // Get the current document and database Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // Start a transaction using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Open the Layer table for read LayerTable acLyrTbl; acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead) as LayerTable; // Step through each layer and update those that start with 'Door' foreach (ObjectId acObjId in acLyrTbl) { // Open the Layer table record for read LayerTableRecord acLyrTblRec; acLyrTblRec = acTrans.GetObject(acObjId, OpenMode.ForRead) as LayerTableRecord; // Check to see if the layer's name starts with 'Door' if (acLyrTblRec.Name.StartsWith("Door", StringComparison.OrdinalIgnoreCase) == true) { // Check to see if the layer is current, if so then do not freeze it if (acLyrTblRec.ObjectId != acCurDb.Clayer) { // Change from read to write mode acLyrTblRec.UpgradeOpen(); // Freeze the layer acLyrTblRec.IsFrozen = true; } } } // Commit the changes and dispose of the transaction acTrans.Commit(); } }