5.1.4. Обновление открытых объектов и отказ от произведённых обновлений

Источник здесь.[перевод не проверен][переводчик: bandero]

    После открытия объекта, используя любой из методов GetObject или Open, вы можете изменить текущий режим объекта методом UpgradeOpen или DowngradeOpen. Метод UpgradeOpen изменяет режим открытия объекта с чтения на запись, а DowngradeOpen – с записи на чтение. Вам не нужно попарно вызывать DowngraeOpen для каждого вызова UpgradeOpen, т.к. последующего закрытия объекта или завершения транзакции, будет достаточно для завершения редактирования объекта1.

    Когда вы открываете объект - делайте это сразу в том режиме, в котором хотите его использовать. Не следует открывать объект для записи, если вам нужно только просмотреть его.  Эффективнее просматривать свойства объекта открыв его только для чтения, чем выполнять то же самое действие, но при этом открыв его для записи.

    Открытие объекта на запись вызывает начало регистрации (filing) процедуры отката (undo) для этого объекта. Регистрация отката используется для того, чтобы отследить изменения объекта - это позволит отказаться от любых2 изменений. Если вы не уверены, что вам действительно нужна модификация объекта, то лучше открыть объект на чтение и затем3 - перейти в режим записи. Это поможет сократить ресурсные затраты вашей программы.

    Примером, использования метода UpgradeOpen, может быть просмотр объекта для определения, соответствует ли он условию, и если условие соблюдается тогда, можно обновить объект с режима чтения на запись, чтобы его отредактировать.

Открытие для уведомления

    Точно так же, если объект открывается для уведомления (Notify) и вы получаете уведомление4, можете использовать метод UpgradeFromNotify для обновления режима на запись. Тогда как, использование DowngradeToNotify понижает режим объекта до уведомления (Notify). UpgradeFromNotify и DowngradeToNotify зарезервированы для использования в методах, предназначенных в случаях, когда объект меняет свой режим открытия, для безопасного его редактирования5.

Код VB.NET

   1:  Imports Autodesk.AutoCAD.Runtime
   2:  Imports Autodesk.AutoCAD.ApplicationServices
   3:  Imports Autodesk.AutoCAD.DatabaseServices 
   4:   
   5:  <CommandMethod("FreezeDoorLayer")> _
   6:  Public Sub FreezeDoorLayer() 
   7:   
   8:    '' Получение текущего документа и базы данных
   9:    Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
  10:    Dim acCurDb As Database = acDoc.Database 
  11:   
  12:    '' Старт транзакции
  13:    Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() 
  14:   
  15:        '' Открытие таблицы Слоёв для чтения
  16:        Dim acLyrTbl As LayerTable
  17:        acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead) 
  18:   
  19:        '' Перебор слоёв и обновление тех, которые начинаются с ‘Door’
  20:        For Each acObjId As ObjectId In acLyrTbl
  21:   
  22:            '' Открытие записи таблицы Слоёв для чтения
  23:            Dim acLyrTblRec As LayerTableRecord
  24:            acLyrTblRec = acTrans.GetObject(acObjId, OpenMode.ForRead)
  25:   
  26:            '' Проверка, если имя слоя начинается с ‘Door’
  27:            If (acLyrTblRec.Name.StartsWith("Door", _
  28:  StringComparison.OrdinalIgnoreCase) = True) Then
  29:                '' Проверка, если это текущий слой, тогда не замораживаем его
  30:           If acLyrTblRec.ObjectId <> acCurDb.Clayer Then
  31:                    '' Изменение режима с чтения на запись
  32:                    acLyrTblRec.UpgradeOpen() 
  33:   
  34:                    '' Замораживаем слой
  35:                    acLyrTblRec.IsFrozen = True
  36:                End If
  37:            End If
  38:        Next
  39:   
  40:        '' Фиксация изменений и высвобождение транзакции
  41:        acTrans.Commit()
  42:    End Using
  43:  End Sub 

Код C#

   1:  using Autodesk.AutoCAD.Runtime;
   2:  using Autodesk.AutoCAD.ApplicationServices;
   3:  using Autodesk.AutoCAD.DatabaseServices;
   4:   
   5:  [CommandMethod("FreezeDoorLayer")]
   6:  public static void FreezeDoorLayer()
   7:  {
   8:    // Получение текущего документа и базы данных
   9:    Document acDoc = Application.DocumentManager.MdiActiveDocument;
  10:    Database acCurDb = acDoc.Database; 
  11:   
  12:    // Старт транзакции
  13:    using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  14:    {
  15:        // Открытие таблицы Слоёв для чтения
  16:        LayerTable acLyrTbl;
  17:        acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId,
  18:  OpenMode.ForRead) as LayerTable; 
  19:   
  20:        // Перебор слоёв и обновление тех, которые начинаются с ‘Door’
  21:        foreach (ObjectId acObjId in acLyrTbl)
  22:        {
  23:            // Открытие записи таблицы Слоёв для чтения
  24:            LayerTableRecord acLyrTblRec;
  25:            acLyrTblRec = acTrans.GetObject(acObjId,
  26:  OpenMode.ForRead) as LayerTableRecord; 
  27:   
  28:            // Проверка, если имя слоя начинается с ‘Door’
  29:            if (acLyrTblRec.Name.StartsWith("Door",
  30:  StringComparison.OrdinalIgnoreCase) == true)
  31:            {
  32:                // Проверка, если это текущий слой, тогда не замораживаем его
  33:                if (acLyrTblRec.ObjectId != acCurDb.Clayer)
  34:                {
  35:                    // Изменение режима с чтения на запись
  36:                    acLyrTblRec.UpgradeOpen(); 
  37:   
  38:                    // Замораживаем слой
  39:                    acLyrTblRec.IsFrozen = true;
  40:                }
  41:            }
  42:        } 
  43:   
  44:        // Фиксация изменений и высвобождение транзакции
  45:        acTrans.Commit();
  46:    }
  47:  }

Примечания переводчика:
1 - неуверен в правильности перевода
2 - сделанных в нем
3 - при необходимости
4 - получаете объект в режиме уведомления
5 - я не понял

Comments