zoukankan      html  css  js  c++  java
  • AutoCAD中的扩展字典及扩展记录(C#)

    在学习CAD扩展记录的过程中,遇到了一些问题,也积累了一些经验,现在给大家分享一些我的学习心得。在学习扩展字典之前需要读者了解cad的组码,也就是DxfCode。感兴趣的也可以了解一下扩展数据的相关内容(后面有时间也会分享一下,因为扩展数据、扩展字典和DxfCode组码之间有密切的关系)。

    一个CAD对象只能拥有一个扩展字典,而扩展字典下面可以包含多个扩展记录。打个比方,可以这么理解,如果扩展字典相当于excel文件,那么一个扩展记录就相当于excel中的一个表单sheet对象,扩展记录中存储的数据就相当于表单sheet中的数据。

    使用扩展记录可以向对象中保存一些属性数据,以便后续提取之用,这是很有用的。比如说可以向一个多段线(代表一根管线,或是其他)中存储一些施工方面的数据信息,例如施工标段、桩号范围、施工完成时间等,以后再打开图的时候,就知道这段管线是哪个施工单位施工的,什么时间完成的等等,便于查看和统计。CAD程序自身的属性对话框是无法记录这些信息的。

    向对象添加扩展记录一般分为三个步骤:

    1 将添加的数据构成一个类

    2 编写扩展方法,包括扩展记录的添加、读取、删除、修改

    3 调用扩展方法进行操作

    界面如下:

    下面列出主要的代码

    1 将需要添加的数据构成一个类,主要包括施工标段、信息、桩号、完成时间等属性

     1  public class XDataClass
     2     {
     3         public string BiaoDuan { get; set; }//施工标段
     4         public string Information { get; set; }//附加到对象上的信息
     5         public double StationStart { get; set; }//起始桩号
     6         public double StationEnd { get; set; }//终止桩号
     7         public double Length { get; private set; }//长度
     8         public DateTime OverTime { get; set; }//完成时间
     9         public string XRecordName { get; set; } //扩展记录名称
    10         public XDataClass() { }
    11         public XDataClass(string xrecordName)
    12         {
    13             XRecordName = xrecordName;
    14         }
    15         /// <summary>
    16         /// 将扩展数据实体类转化成typevaluelist类型
    17         /// </summary>
    18         /// <param name="xdataClass"></param>
    19         /// <returns></returns>
    20         public static TypedValueList ClassToTypeValueList(XDataClass xdataClass)
    21         {
    22             TypedValueList tvList = new TypedValueList
    23             {
    24                 {DxfCode.Text, xdataClass.BiaoDuan },
    25                 {DxfCode.Text, xdataClass.Information },
    26                 {DxfCode .Real ,xdataClass.StationStart  },
    27                 {DxfCode.Real ,xdataClass .StationEnd  },
    28                 {DxfCode.Text ,xdataClass .OverTime .ToString ("d") },
    29                 {DxfCode.Text ,xdataClass.XRecordName  },
    30             }; 
    31             return tvList;
    32         }
    33         /// <summary>
    34         /// 将typevaluelist类型的数据转换成实体类
    35         /// </summary>
    36         /// <param name="list"></param>
    37         /// <returns></returns>
    38         public static XDataClass TypeValueListToClass(TypedValueList list)
    39         {
    40             XDataClass xdataClass = new XDataClass()
    41             {
    42                 BiaoDuan = list[0].Value.ToString(),
    43                 Information = list[1].Value.ToString(),
    44                 StationStart = Convert.ToDouble(list[2].Value),
    45                 StationEnd = Convert.ToDouble(list[3].Value),
    46                 OverTime = Convert.ToDateTime(list[4].Value),
    47                 XRecordName = list[5].Value.ToString(),
    48                 Length = Math.Abs(Convert.ToDouble(list[3].Value) - Convert.ToDouble(list[2].Value))
    49             };
    50             return xdataClass;
    51         }
    52     }

    2  编写扩展方法,包括扩展记录的添加、读取、删除、修改

      1 #region 对象的扩展记录的添加、删除、修改
      2         /// <summary>
      3         ///  添加扩展记录,如果没有扩展字典,那就创建扩展字典
      4         /// </summary>
      5         /// <param name="objId">对象的objectid</param>
      6         /// <param name="xRecordSearchKey">扩展记录名称</param>
      7         /// <param name="values">扩展记录的内容</param>
      8         /// <returns></returns>
      9         public static bool AddXRecordToObj(this ObjectId objId, string xRecordSearchKey, TypedValueList values)
     10         {
     11             //添加扩展记录之前,先创建对象的扩展字典
     12             DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开
     13             if (obj.ExtensionDictionary.IsNull)//如果对象无扩展字典,那就给创建
     14             {
     15                 obj.UpgradeOpen();//切换对象为写的状态
     16                 obj.CreateExtensionDictionary();//为对象创建扩展字典,一个对象只能拥有一个扩展字典
     17                 obj.DowngradeOpen();//将对象切换为读的状态
     18             }
     19             //打开对象的扩展字典
     20             DBDictionary dict = obj.ExtensionDictionary.GetObject(OpenMode.ForRead) as DBDictionary;
     21             //如果扩展字典中已包含指定的扩展记录对象  
     22             if (dict.Contains(xRecordSearchKey))
     23             {
     24                  return false;//如果包含有指定的扩展记录,那就退出
     25             }
     26             else //若没有包含扩展记录,则创建一个
     27             {
     28                 Xrecord xrec = new Xrecord();//为对象创建一个扩展记录 
     29                 xrec.Data = values;//指定扩展记录的内容,这里用到了自定义类型转换,TypedValueList-->ResultBuffer
     30                 dict.UpgradeOpen();//将扩展字典切换为写的状态,以便添加一个扩展记录
     31                 ObjectId xrecId = dict.SetAt(xRecordSearchKey, xrec);//在扩展字典中加入新建的扩展记录,并指定它的搜索关键字
     32                 objId.Database.TransactionManager.AddNewlyCreatedDBObject(xrec, true);
     33                 dict.DowngradeOpen();//将扩展字典切换为读的状态
     34                 return true; 
     35             }
     36         }
     37 
     38         /// <summary>
     39         /// 用于替换扩展字典中的整个一条扩展记录
     40         /// </summary>
     41         /// <param name="objId">对象id</param>
     42         /// <param name="xRecordSearchKey">扩展记录的名称</param>
     43         /// <param name="values">扩展记录的内容</param>
     44         public static bool ModObjXrecord(this ObjectId objId, string xRecordSearchKey, TypedValueList values)
     45         {
     46             DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
     47             ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典id
     48             if (dictId.IsNull)
     49             {
     50                 return false;//若对象没有扩展字典,则返回 
     51             }
     52             //如果对象有扩展字典,则以读的方式打开
     53             DBDictionary dict = dictId.GetObject(OpenMode.ForRead) as DBDictionary;
     54             if (!dict.Contains(xRecordSearchKey))
     55             {
     56                 return false;//如果扩展字典中没有包含指定关键字的扩展记录,则返回 ;
     57             }
     58             ObjectId xrecordId = dict.GetAt(xRecordSearchKey);//获取扩展记录的id
     59             Xrecord xrecord = xrecordId.GetObject(OpenMode.ForWrite) as Xrecord;
     60             xrecord.Data = values;//覆盖原来的数据,因为values有了新的指向
     61             xrecord.DowngradeOpen();//将扩展记录切换为读的状态
     62             return true;
     63         }
     64 
     65         /// <summary>
     66         /// 获取对象的扩展字典中的扩展记录
     67         /// </summary>
     68         /// <param name="objId">对象的id</param>
     69         /// <param name="xRecordSearchKey">扩展记录名称</param>
     70         /// <returns></returns>
     71         public static TypedValueList GetObjXrecord(this ObjectId objId, string xRecordSearchKey)
     72         {
     73             DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
     74             ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典的id
     75             if (dictId.IsNull)
     76             {
     77                 //MessageBox.Show("没有扩展字典");
     78                 return null;//若对象没有扩展字典,则返回null
     79             }
     80             DBDictionary dict = dictId.GetObject(OpenMode.ForRead) as DBDictionary;//获取对象的扩展字典
     81             if (!dict.Contains(xRecordSearchKey))
     82             {
     83                 return null;//如果扩展字典中没有包含指定关键字的扩展记录,则返回null;
     84             }
     85             //先要获取对象的扩展字典或图形中的有名对象字典,然后才能在字典中获取要查询的扩展记录
     86             ObjectId xrecordId = dict.GetAt(xRecordSearchKey);//获取扩展记录对象的id
     87             Xrecord xrecord = xrecordId.GetObject(OpenMode.ForRead) as Xrecord;//根据id获取扩展记录对象
     88             TypedValueList values = xrecord.Data;
     89             return values;//values 数组应该是有先后顺序的
     90         }
     91 
     92         /// <summary>
     93         ///用于删除对象扩展字典中的指定的扩展记录
     94         /// </summary>
     95         /// <param name="objId">对象id</param>
     96         /// <param name="xRecordSearchKey"> 扩展记录名称</param>
     97         public static bool DelObjXrecord(this ObjectId objId, string xRecordSearchKey)
     98         {
     99             DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
    100             ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典id
    101             if (dictId.IsNull)
    102             {
    103                 return false;//若对象没有扩展字典,则返回 
    104             }
    105             //如果对象有扩展字典,则以读的方式打开
    106             DBDictionary dict = dictId.GetObject(OpenMode.ForRead) as DBDictionary;
    107             if (dict.Contains(xRecordSearchKey))//如果扩展字典中包含指定关键字的扩展记录,则删除;
    108             {
    109                 dict.UpgradeOpen();//切换为写的状态
    110                 dict.Remove(xRecordSearchKey);//删除扩展记录
    111                 dict.DowngradeOpen();//切换为读的状态
    112             }
    113             return true;
    114         }
    115         
    116         /// <summary>
    117         /// 删除对象的扩展字典下的所有的扩展记录
    118         /// 2018年4月7日09:44:12
    119         /// </summary>
    120         /// <param name="objId"></param>
    121         public static bool DelObjAllXrecords(this ObjectId objId)
    122         {
    123             DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
    124             ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典id
    125             if (dictId.IsNull)
    126             {
    127                 return false;//若对象没有扩展字典,则返回 
    128             }
    129             //如果对象有扩展字典,则以读的方式打开
    130             DBDictionary dict = dictId.GetObject(OpenMode.ForWrite) as DBDictionary;
    131             //获取扩展字典下的所有扩展记录名称集合 Keys 
    132 133             List<string> listKeys = new List<string>();
    134             foreach (var item in dict)//获取扩展字典中的所有条目,也就是所有的扩展记录的key
    135             {
    136                 listKeys.Add(item.Key);
    137             }
    138             foreach (var key in listKeys)//根据key,删除扩展字典中的每一个条目(也就是扩展记录)
    139             {
    140                 dict.Remove(key);
    141             }
    142             dict.DowngradeOpen();//切换为读的状态 
    143             return true;
    144         }
    145 
    146 
    147         /// <summary>
    148         /// 删除对象的扩展字典,因为每个对象只能拥有一个扩展字典,所以给定对象的objectID就好了
    149         ///  2018年4月7日09:17:44 
    150         /// </summary>
    151         /// <param name="objId"></param>
    152         public static bool DeleteObjExtensionDictionary(this ObjectId objId)
    153         {
    154             DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
    155             ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典的ID
    156             if (dictId.IsNull)
    157             {
    158                 return false;    //没有扩展字典
    159             }
    160             //有扩展字典 161             obj.UpgradeOpen();//切换对象为写的状态
    162 objId.DelObjAllXrecords(); //调用上面的方法,在删除扩展字典之前要先删除扩展记录
    163 obj.ReleaseExtensionDictionary();//移除对象的扩展字典,一个对象只能拥有一个扩展字典 164 obj.DowngradeOpen();//将对象切换为读的状态 165 return true; 166 } 167 #endregion

    3调用扩展方法

      a 添加扩展记录

     1  //btn  添加扩展记录
     2         XDataClass PipeXdataClass = new XDataClass(Enum_XRcordName.pipe_whlkx.ToString());
     3         ObjectId selectedObjId = ObjectId.Null;
     4         private void btnAddXData_Click(object sender, EventArgs e)
     5         {
     6             if (CheckValue() == false)
     7             {
     8                 return;
     9             }
    10             _instance.Hide();
    11             Document doc = AcadApp.DocumentManager.MdiActiveDocument;
    12             Database db = doc.Database;
    13             Editor ed = doc.Editor; 
    14             PromptEntityResult entityResult = ed.GetEntity("
    请选择一个多段线对象");//单个拾取对象 
    15             if (entityResult.Status != PromptStatus.OK)
    16             {
    17                 _instance.Show();
    18                 return;
    19             }
    20             GetDataFromControls(PipeXdataClass);//私有函数,将控件中的数据填充到实体类中
    21             //获取对象的ID
    22             ObjectId objId = entityResult.ObjectId; 
    23             bool result = false;
    24             using (DocumentLock docLock = doc.LockDocument())
    25             using (Transaction trans = db.TransactionManager.StartTransaction())
    26             {
    27                 //将xdataCalss类型的数据转换成一个typevalue型的列表
    28                 TypedValueList values = XDataClass.ClassToTypeValueList(PipeXdataClass);
    29                 result = objId.AddXRecordToObj(PipeXdataClass.XRecordName, values);
    30                 trans.Commit();
    31             }
    32             if (result)
    33             {
    34                 ed.WriteMessage("
    对象的扩展数据添加成功!");
    35             }
    36             else
    37             {
    38                 ed.WriteMessage("
    对象已经有扩展数据");
    39             }
    40             _instance.Show();
    41         }

      

      b 读取扩展记录 

     1 //btn 读取扩展记录
     2         private void btnReadXData_Click(object sender, EventArgs e)
     3         {
     4             _instance.Hide();
     5             ClearContent();//清空控件中的内容
     6             Document doc = AcadApp.DocumentManager.MdiActiveDocument;
     7             Database db = doc.Database;
     8             Editor ed = doc.Editor;
     9             //开始事务处理
    10             using (DocumentLock docLock = doc.LockDocument())
    11             using (Transaction trans = db.TransactionManager.StartTransaction())
    12             {
    13                 PromptEntityResult entityResult = ed.GetEntity("
    请选择一个对象");//拾取单个对象
    14                 if (entityResult.Status != PromptStatus.OK)
    15                 {
    16                     ed.WriteMessage("
    取消了选择");
    17                     _instance.Show();
    18                     return;
    19                 }
    20                 //获取对象的ID
    21                 ObjectId objId = entityResult.ObjectId;
    22                 TypedValueList list = objId.GetObjXrecord(PipeXdataClass.XRecordName);
    23                 if (list is null)
    24                 {
    25                     ed.WriteMessage("
    该对象没有扩展记录");
    26                     _instance.Show();
    27                     return;
    28                 }
    29                 if (list.Count <= 0)
    30                 {
    31                     ed.WriteMessage("
    有扩展记录,但是记录为空");
    32                     _instance.Show();
    33                     return;
    34                 }
    35                 else
    36                 {
    37                     PipeXdataClass = XDataClass.TypeValueListToClass(list);
    38                     SetDataToControls(PipeXdataClass);//向控件中填充数据
    39                     ed.WriteMessage("
    对象扩展数据读取成功");
    40                     selectedObjId = objId;
    41                 }
    42             }
    43             _instance.Show();
    44         }

      c 删除扩展记录

     1         //btn 删除
     2         private void btnDeleteXData_Click(object sender, EventArgs e)
     3         {
     4             _instance.Hide();
     5             Document doc = AcadApp.DocumentManager.MdiActiveDocument;
     6             Database db = doc.Database;
     7             Editor ed = doc.Editor;
     8             //开始事务处理
     9             using (DocumentLock docLock = doc.LockDocument())
    10             using (Transaction trans = db.TransactionManager.StartTransaction())
    11             {
    14                 PromptSelectionResult ss1 = ed.GetSelection();//框选对象
    15                 if (ss1.Status != PromptStatus.OK)
    16                 {
    17                     ed.WriteMessage("
    取消了选择");
    18                     _instance.Show();
    19                     return;
    20                 }
    21                 //获取对象的ID
    22                 List<ObjectId> listObjIds = ss1.Value.GetObjectIds().ToList();
    23                 int count = 0;
    24                 listObjIds.ForEach(objId =>
    25                 {
    26                     if (objId.DeleteObjExtensionDictionary())
    27                     {
    28                         ed.WriteMessage("
    删除成功");
    29                         count++;
    30                     }
    31                 });
    32                 //ObjectId objId = entityResult.ObjectId;
    33                 //2018年4月7日09:50:35,经验证,必须先删除扩展字典下的所有的扩展记录,才能删除对象的扩展字典
    34                 //否则会出现错误:eContainerNotEmpty ,容器不为空
    35                 //objId.DelObjAllXrecords();
    36                 //objId.DeleteObjExtensionDictionary();
    37                 trans.Commit();
    38                 ed.WriteMessage("
    操作完成,总共删除{0}个扩展记录", count);
    39             } 
    40             _instance.Show();
    41         }

     修改扩展记录可以自己写一下,比较简单。

      下面给出一张图关于扩展字典和扩展记录的示意图,便于理解之间的关系。

  • 相关阅读:
    tp3.2自动验证
    tp3.2 前端截取字符串
    tp3.2前端页面格式化时间
    tp3.2 php sdk上传七牛云
    汇编语言:编写code段中的代码,用push指令将a段中的前8个字型数据,逆序存储b段中
    编写code段中的代码,将a段和b段中的数据依次相加,将结果存到c段中
    实现一次用内存0:0-0:15单元中的内容改写程序中的数据,完成程序:
    编程,向内存0:200~0:23F依次传送数据0~63(3FH),程序中只能使用9条指令,9条指令包括 mov ax,4c00h 和 int 21h
    vue 常用操作
    js try catch 获取错误信息
  • 原文地址:https://www.cnblogs.com/whlkx/p/8748972.html
Copyright © 2011-2022 走看看