qq1254582201 发表于 2024-9-6 09:48:45

【转载】AutoCAD二次开发&创建和获取扩展字典对象与扩展记录数据

本帖最后由 qq1254582201 于 2024-9-6 10:00 编辑

这是一个与学习创建和获取扩展字典对象与扩展记录数据相关的内容。我们知道在南方cass中有一部分数据是存在扩展数据xdata属性中,其中宗地的宗地基本属性就是印证了这一点。而我们接下了的学习是字典Dictionary扩展数据、扩展记录数据Xrecord。这对了解AutoCAD扩展数据具有一定帮助。

工程的代码是摘自相关网站,源代码使用的是..net6.0,由于本次使用的是AutoCAD2010,因此版本为net3.5,而相应的函数是在原有类的基础上扩展得来的,比如string.IsNullOrWhiteSpace(),单独写一个关于string的扩展函数IsNullOrWhiteSpace()。而代码中出现的nameof函数,用于获取类型等信息标记异常信息,这里使用另外的一些标记代替。具体可以参考提供的源代码。下面的源代码中函数GetObject是一泛型方法,其中还使用了where关键字对基类进行了约束。其他函数的使用看注释即可。

相关扩展字典操作类。

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HandleXDictionaryXrecords
{
    public static class Extension
    {
      public static T GetObject<T>(
       this ObjectId id,
       OpenMode mode = OpenMode.ForRead,
       bool openErased = false,
       bool forceOpenOnLockedLayer = false)
       where T : DBObject
      {
            if (id.IsNull)
                throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NullObjectId);
            Transaction tr = id.Database.TransactionManager.TopTransaction;
            if (tr == null)
                throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions);
            return (T)tr.GetObject(id, mode, openErased, forceOpenOnLockedLayer);
      }
      /// <summary>
      /// 获取扩展字典
      /// </summary>
      /// <param name="source"></param>
      /// <returns></returns>
      public static DBDictionary TryGetExtensionDictionary(this DBObject source)
      {
          if (source == null)
            throw new ArgumentNullException("source为空");
          ObjectId dictId = source.ExtensionDictionary;
          if (dictId == ObjectId.Null)
          {
            return null;
          }
          return dictId.GetObject<DBDictionary>();
      }
      /// <summary>
      /// 获取或创建字典
      /// </summary>
      /// <param name="source"></param>
      /// <returns></returns>
      public static DBDictionary GetOrCreateExtensionDictionary(this DBObject source)
      {
          if (source == null)
            throw new ArgumentNullException("source为空");
          if (source.ExtensionDictionary == ObjectId.Null)
          {
            source.UpgradeOpen();
            source.CreateExtensionDictionary();
          }
          return source.ExtensionDictionary.GetObject<DBDictionary>();
      }
      /// <summary>
      /// 获取扩展字典
      /// </summary>
      /// <param name="source">数据对象</param>
      /// <param name="key">键</param>
      /// <returns></returns>
      public static ResultBuffer GetXDictionaryXrecordData(this DBObject source, string key)
      {
          if (source == null)
            //throw new ArgumentNullException(nameof(source));
            throw new ArgumentNullException("source为空");
          //if (string.IsNullOrWhiteSpace(key))
          if (key.IsNullOrWhiteSpace())
            throw new ArgumentNullException("key或为空");
          DBDictionary xdict = source.TryGetExtensionDictionary();
          if (xdict == null)
          {
            return null;
          }
          return xdict.GetXrecordData(key);
      }
      /// <summary>
      /// 设置字典
      /// </summary>
      /// <param name="target"></param>
      /// <param name="key"></param>
      /// <param name="values"></param>
      public static void SetXDictionaryXrecordData(this DBObject target, string key, params TypedValue[] values)
      {
          target.SetXDictionaryXrecordData(key, new ResultBuffer(values));
      }
      /// <summary>
      /// 创建字典
      /// </summary>
      /// <param name="target"></param>
      /// <param name="key"></param>
      /// <param name="data"></param>
      public static void SetXDictionaryXrecordData(this DBObject target, string key, ResultBuffer data)
      {
          if (target == null)
            //throw new ArgumentNullException(nameof(target));
            throw new ArgumentNullException("target为空");
          //if (string.IsNullOrWhiteSpace(key))
          if (key.IsNullOrWhiteSpace())
            //throw new ArgumentNullException(nameof(key));
            throw new ArgumentNullException("key或为空");
          target.GetOrCreateExtensionDictionary().SetXrecordData(key, data);
      }
      /// <summary>
      /// 获取扩展记录数据
      /// </summary>
      /// <param name="dict"></param>
      /// <param name="key"></param>
      /// <returns></returns>
      public static ResultBuffer GetXrecordData(this DBDictionary dict, string key)
      {
          if (dict == null)
            //throw new ArgumentNullException(nameof(dict));
            throw new ArgumentNullException("dict为空");
          if (!dict.Contains(key))
          {
            return null;
          }
          ObjectId id = (ObjectId)dict;
          if (id.ObjectClass != RXObject.GetClass(typeof(Xrecord)))
            return null;
          return id.GetObject<Xrecord>().Data;
      }
      /// <summary>
      /// 设置扩展记录数据
      /// </summary>
      /// <param name="dict"></param>
      /// <param name="key"></param>
      /// <param name="data"></param>
      public static void SetXrecordData(this DBDictionary dict, string key, ResultBuffer data)
      {
          if (dict == null)
         //   throw new ArgumentNullException(nameof(dict));
            throw new ArgumentNullException("dict为空");
          //if (string.IsNullOrWhiteSpace(key))
         if( key.IsNullOrWhiteSpace())
            //throw new ArgumentNullException(nameof(key));
               throw new ArgumentNullException("key或为空");
          Transaction tr = dict.Database.TransactionManager.TopTransaction;
          if (tr == null)
            throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions);
          Xrecord xrec;
          if (dict.Contains(key))
          {
            xrec = ((ObjectId)dict).GetObject<Xrecord>(OpenMode.ForWrite);
          }
          else
          {
            dict.UpgradeOpen();
            xrec = new Xrecord();
            dict.SetAt(key, xrec);
            tr.AddNewlyCreatedDBObject(xrec, true);
          }
          xrec.Data = data;
      }

    }


}
最后是一个测试类。

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HandleXDictionaryXrecords
{
    /// <summary>
    /// 测试类
    /// </summary>
    class XrecordTest
    {

      
      public static void XrecordTest() {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityResult per = ed.GetEntity("\n选择一个实体: ");
            if (per.Status == PromptStatus.OK)
            {
                using (var tr = db.TransactionManager.StartTransaction())
                {
                  Entity ent = (Entity)tr.GetObject(per.ObjectId, OpenMode.ForRead);
                  ResultBuffer data = ent.GetXDictionaryXrecordData("TestXrec");
                  if (data == null)
                  {
                        ed.WriteMessage("\n实体不存在交 'TextXrec' Xrecord记录, 将添加到Xrecord记录中");
                        ent.SetXDictionaryXrecordData("TestXrec", new TypedValue(1, "foo"), new TypedValue(70, 42));
                  }
                  else
                  {
                        foreach (TypedValue tv in data.AsArray())
                        {
                            ed.WriteMessage("\nTypeCode: {"+tv.TypeCode.ToString()+"}, Value: {"+tv.Value.ToString()+"}");
                        }
                  }
                  tr.Commit();
                }
            }
      }
    }
}
在visual studio中编译好源代码后,在命令行输入netload加载生成的dll,然后再运行XRECTEST命令,按照相关步骤执行即可。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/u010608964/article/details/82026368

qq1254582201 发表于 2024-9-6 10:11:33

/// <summary>
      /// Add or edit a Xrecord data in a named dictionary (the dictionary and xrecord are created if not already exist)
      /// </summary>
      /// <param name="dictName">The dictionary name</param>
      /// <param name="key">the xrecord key</param>
      /// <param name="resbuf">the xrecord data</param>
      public void SetXrecord(string dictName, string key, ResultBuffer resbuf)
      {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary NOD =
                  (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                DBDictionary dict;
                if (NOD.Contains(dictName))
                {
                  dict = (DBDictionary)tr.GetObject(NOD.GetAt(dictName), OpenMode.ForWrite);
                }
                else
                {
                  dict = new DBDictionary();
                  NOD.UpgradeOpen();
                  NOD.SetAt(dictName, dict);
                  tr.AddNewlyCreatedDBObject(dict, true);
                }
                Xrecord xRec = new Xrecord();
                xRec.Data = resbuf;
                dict.SetAt(key, xRec);
                tr.AddNewlyCreatedDBObject(xRec, true);
                tr.Commit();
            }
      }

      /// <summary>
      /// Gets an xrecord data in a named dictionary
      /// </summary>
      /// <param name="dictName">The dictionary name</param>
      /// <param name="key">The xrecord key</param>
      /// <returns>The xrecord data or null if the dictionary or the xrecord do not exist</returns>
      public ResultBuffer GetXrecord(string dictName, string key)
      {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary NOD =
                  (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                if (!NOD.Contains(dictName))
                  return null;
                DBDictionary dict = tr.GetObject(NOD.GetAt(dictName), OpenMode.ForRead) as DBDictionary;
                if (dict == null || !dict.Contains(key))
                  return null;
                Xrecord xRec = tr.GetObject(dict.GetAt(key), OpenMode.ForRead) as Xrecord;
                if (xRec == null)
                  return null;
                return xRec.Data;
            }
      }

页: [1]
查看完整版本: 【转载】AutoCAD二次开发&创建和获取扩展字典对象与扩展记录数据