ADN Open CIS
Сообщество программистов Autodesk в СНГ

30/04/2014

UNDO удаляет обновленные записи словаря

У меня есть команда, которая добавляет новую запись в Словарь Именованных Объектов (NOD) или обновляет значение существующего.

Проблема в том, что когда я запускаю команду дважды (во второй раз запись уже есть, так что в этот раз только обновляется ее значение) и когда мы запускаем команду _UNDO, тогда вместо того, чтобы вернуть предыдущее значение записи NOD, она удаляется полностью.

Код - C#: [Выделить]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using acApp = Autodesk.AutoCAD.ApplicationServices.Application;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6.  
  7. namespace CsMgdAcad1
  8. {
  9.   public class AEN1Commands
  10.   {
  11.     [CommandMethod("UpdateXrecord")]
  12.     static public void UpdateXrecord()
  13.     {
  14.       const string kMyData = "MYDATA";
  15.  
  16.       Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor;
  17.  
  18.       Database db = HostApplicationServices.WorkingDatabase;
  19.       using (Transaction tr =
  20.         db.TransactionManager.StartTransaction())
  21.       {
  22.         DBDictionary nod =
  23.           (DBDictionary)tr.GetObject(
  24.             db.NamedObjectsDictionaryId, OpenMode.ForRead);
  25.  
  26.         if (nod.Contains(kMyData))
  27.         {
  28.           // Обновляем данные
  29.           Xrecord xrec =
  30.             (Xrecord)tr.GetObject(
  31.               nod.GetAt(kMyData), OpenMode.ForRead);
  32.  
  33.           int val = (int)xrec.Data.AsArray()[0].Value;
  34.           Xrecord newXrec = new Xrecord();
  35.           newXrec.Data = new ResultBuffer(
  36.             new TypedValue[]
  37.             {
  38.               new TypedValue((int)LispDataType.Int32, val + 1)
  39.             });
  40.           nod.UpgradeOpen();
  41.           nod.SetAt(kMyData, newXrec);
  42.           tr.AddNewlyCreatedDBObject(newXrec, true);
  43.           ed.WriteMessage(
  44.             "Обновляем данные " + (val + 1).ToString());
  45.         }
  46.         else
  47.         {
  48.           // Инициализируем данные
  49.           Xrecord xrec = new Xrecord();
  50.           xrec.Data = new ResultBuffer(
  51.             new TypedValue[]
  52.             {
  53.               new TypedValue((int)LispDataType.Int32, 1)
  54.             });
  55.           nod.UpgradeOpen();
  56.           nod.SetAt(kMyData, xrec);
  57.           ed.WriteMessage("Инициализируем данные 1");
  58.         }
  59.  
  60.         tr.Commit();
  61.       }
  62.     }
  63.   }
  64. }

Решение

Есть два метода для решения:

a) Когда обновляете существующую запись – обновляйте и существующую Xrecord, относящуюся к этой записи – просто изменяйте её данные:

Код - C#: [Выделить]
  1. Xrecord xrec =
  2.   (Xrecord)tr.GetObject(nod.GetAt(kMyData), OpenMode.ForWrite);
  3. int val = (int)xrec.Data.AsArray()[0].Value;
  4. xrec.Data = new ResultBuffer(
  5.   new TypedValue[]
  6.   {
  7.     new TypedValue((int)LispDataType.Int32, val + 1)
  8.   });
  9. ed.WriteMessage("Данные обновлены " + (val + 1).ToString());

b) Когда обновляете запись словаря, тогда перед обновлением её новой Xrecord, тогда удалите сначала существующую запись:

Код - C#: [Выделить]
  1. Xrecord xrec =
  2.   (Xrecord)tr.GetObject(nod.GetAt(kMyData), OpenMode.ForRead);
  3. int val = (int)xrec.Data.AsArray()[0].Value;
  4. Xrecord newXrec = new Xrecord();
  5. newXrec.Data = new ResultBuffer(
  6.   new TypedValue[]
  7.   {
  8.     new TypedValue((int)LispDataType.Int32, val + 1)
  9.   });
  10. nod.UpgradeOpen();
  11. // Сначала удаляем существующую запись
  12. nod.Remove(kMyData);
  13. nod.SetAt(kMyData, newXrec);
  14. tr.AddNewlyCreatedDBObject(newXrec, true);
  15. ed.WriteMessage("Данные обновлены " + (val + 1).ToString());

Источник: http://adndevblog.typepad.com/autocad/2012/07/undo-removes-updated-dictionary-entry.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=712

Опубликовано 30.04.2014