AutoCAD中的扩展字典及扩展记录(C#)

时间:2022-09-24 23:08:12

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

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

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

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

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

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

3 调用扩展方法进行操作

界面如下:

AutoCAD中的扩展字典及扩展记录(C#)

下面列出主要的代码

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

  public class XDataClass
{
public string BiaoDuan { get; set; }//施工标段
public string Information { get; set; }//附加到对象上的信息
public double StationStart { get; set; }//起始桩号
public double StationEnd { get; set; }//终止桩号
public double Length { get; private set; }//长度
public DateTime OverTime { get; set; }//完成时间
public string XRecordName { get; set; } //扩展记录名称
public XDataClass() { }
public XDataClass(string xrecordName)
{
XRecordName = xrecordName;
}
/// <summary>
/// 将扩展数据实体类转化成typevaluelist类型
/// </summary>
/// <param name="xdataClass"></param>
/// <returns></returns>
public static TypedValueList ClassToTypeValueList(XDataClass xdataClass)
{
TypedValueList tvList = new TypedValueList
{
{DxfCode.Text, xdataClass.BiaoDuan },
{DxfCode.Text, xdataClass.Information },
{DxfCode .Real ,xdataClass.StationStart },
{DxfCode.Real ,xdataClass .StationEnd },
{DxfCode.Text ,xdataClass .OverTime .ToString ("d") },
{DxfCode.Text ,xdataClass.XRecordName },
};
return tvList;
}
/// <summary>
/// 将typevaluelist类型的数据转换成实体类
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public static XDataClass TypeValueListToClass(TypedValueList list)
{
XDataClass xdataClass = new XDataClass()
{
BiaoDuan = list[].Value.ToString(),
Information = list[].Value.ToString(),
StationStart = Convert.ToDouble(list[].Value),
StationEnd = Convert.ToDouble(list[].Value),
OverTime = Convert.ToDateTime(list[].Value),
XRecordName = list[].Value.ToString(),
Length = Math.Abs(Convert.ToDouble(list[].Value) - Convert.ToDouble(list[].Value))
};
return xdataClass;
}
}

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

 #region 对象的扩展记录的添加、删除、修改
/// <summary>
/// 添加扩展记录,如果没有扩展字典,那就创建扩展字典
/// </summary>
/// <param name="objId">对象的objectid</param>
/// <param name="xRecordSearchKey">扩展记录名称</param>
/// <param name="values">扩展记录的内容</param>
/// <returns></returns>
public static bool AddXRecordToObj(this ObjectId objId, string xRecordSearchKey, TypedValueList values)
{
//添加扩展记录之前,先创建对象的扩展字典
DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开
if (obj.ExtensionDictionary.IsNull)//如果对象无扩展字典,那就给创建
{
obj.UpgradeOpen();//切换对象为写的状态
obj.CreateExtensionDictionary();//为对象创建扩展字典,一个对象只能拥有一个扩展字典
obj.DowngradeOpen();//将对象切换为读的状态
}
//打开对象的扩展字典
DBDictionary dict = obj.ExtensionDictionary.GetObject(OpenMode.ForRead) as DBDictionary;
//如果扩展字典中已包含指定的扩展记录对象
if (dict.Contains(xRecordSearchKey))
{
return false;//如果包含有指定的扩展记录,那就退出
}
else //若没有包含扩展记录,则创建一个
{
Xrecord xrec = new Xrecord();//为对象创建一个扩展记录
xrec.Data = values;//指定扩展记录的内容,这里用到了自定义类型转换,TypedValueList-->ResultBuffer
dict.UpgradeOpen();//将扩展字典切换为写的状态,以便添加一个扩展记录
ObjectId xrecId = dict.SetAt(xRecordSearchKey, xrec);//在扩展字典中加入新建的扩展记录,并指定它的搜索关键字
objId.Database.TransactionManager.AddNewlyCreatedDBObject(xrec, true);
dict.DowngradeOpen();//将扩展字典切换为读的状态
return true;
}
} /// <summary>
/// 用于替换扩展字典中的整个一条扩展记录
/// </summary>
/// <param name="objId">对象id</param>
/// <param name="xRecordSearchKey">扩展记录的名称</param>
/// <param name="values">扩展记录的内容</param>
public static bool ModObjXrecord(this ObjectId objId, string xRecordSearchKey, TypedValueList values)
{
DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典id
if (dictId.IsNull)
{
return false;//若对象没有扩展字典,则返回
}
//如果对象有扩展字典,则以读的方式打开
DBDictionary dict = dictId.GetObject(OpenMode.ForRead) as DBDictionary;
if (!dict.Contains(xRecordSearchKey))
{
return false;//如果扩展字典中没有包含指定关键字的扩展记录,则返回 ;
}
ObjectId xrecordId = dict.GetAt(xRecordSearchKey);//获取扩展记录的id
Xrecord xrecord = xrecordId.GetObject(OpenMode.ForWrite) as Xrecord;
xrecord.Data = values;//覆盖原来的数据,因为values有了新的指向
xrecord.DowngradeOpen();//将扩展记录切换为读的状态
return true;
} /// <summary>
/// 获取对象的扩展字典中的扩展记录
/// </summary>
/// <param name="objId">对象的id</param>
/// <param name="xRecordSearchKey">扩展记录名称</param>
/// <returns></returns>
public static TypedValueList GetObjXrecord(this ObjectId objId, string xRecordSearchKey)
{
DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典的id
if (dictId.IsNull)
{
//MessageBox.Show("没有扩展字典");
return null;//若对象没有扩展字典,则返回null
}
DBDictionary dict = dictId.GetObject(OpenMode.ForRead) as DBDictionary;//获取对象的扩展字典
if (!dict.Contains(xRecordSearchKey))
{
return null;//如果扩展字典中没有包含指定关键字的扩展记录,则返回null;
}
//先要获取对象的扩展字典或图形中的有名对象字典,然后才能在字典中获取要查询的扩展记录
ObjectId xrecordId = dict.GetAt(xRecordSearchKey);//获取扩展记录对象的id
Xrecord xrecord = xrecordId.GetObject(OpenMode.ForRead) as Xrecord;//根据id获取扩展记录对象
TypedValueList values = xrecord.Data;
return values;//values 数组应该是有先后顺序的
} /// <summary>
///用于删除对象扩展字典中的指定的扩展记录
/// </summary>
/// <param name="objId">对象id</param>
/// <param name="xRecordSearchKey"> 扩展记录名称</param>
public static bool DelObjXrecord(this ObjectId objId, string xRecordSearchKey)
{
DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典id
if (dictId.IsNull)
{
return false;//若对象没有扩展字典,则返回
}
//如果对象有扩展字典,则以读的方式打开
DBDictionary dict = dictId.GetObject(OpenMode.ForRead) as DBDictionary;
if (dict.Contains(xRecordSearchKey))//如果扩展字典中包含指定关键字的扩展记录,则删除;
{
dict.UpgradeOpen();//切换为写的状态
dict.Remove(xRecordSearchKey);//删除扩展记录
dict.DowngradeOpen();//切换为读的状态
}
return true;
} /// <summary>
/// 删除对象的扩展字典下的所有的扩展记录
/// 2018年4月7日09:44:12
/// </summary>
/// <param name="objId"></param>
public static bool DelObjAllXrecords(this ObjectId objId)
{
DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典id
if (dictId.IsNull)
{
return false;//若对象没有扩展字典,则返回
}
//如果对象有扩展字典,则以读的方式打开
DBDictionary dict = dictId.GetObject(OpenMode.ForWrite) as DBDictionary;
//获取扩展字典下的所有扩展记录名称集合 Keys
List<string> listKeys = new List<string>();
foreach (var item in dict)//获取扩展字典中的所有条目,也就是所有的扩展记录的key
{
listKeys.Add(item.Key);
}
foreach (var key in listKeys)//根据key,删除扩展字典中的每一个条目(也就是扩展记录)
{
dict.Remove(key);
}
dict.DowngradeOpen();//切换为读的状态
return true;
} /// <summary>
/// 删除对象的扩展字典,因为每个对象只能拥有一个扩展字典,所以给定对象的objectID就好了
/// 2018年4月7日09:17:44
/// </summary>
/// <param name="objId"></param>
public static bool DeleteObjExtensionDictionary(this ObjectId objId)
{
DBObject obj = objId.GetObject(OpenMode.ForRead);//以读的方式打开对象
ObjectId dictId = obj.ExtensionDictionary;//获取对象的扩展字典的ID
if (dictId.IsNull)
{
return false; //没有扩展字典
}
//有扩展字典 obj.UpgradeOpen();//切换对象为写的状态
162 objId.DelObjAllXrecords(); //调用上面的方法,在删除扩展字典之前要先删除扩展记录
obj.ReleaseExtensionDictionary();//移除对象的扩展字典,一个对象只能拥有一个扩展字典
obj.DowngradeOpen();//将对象切换为读的状态
return true;
}
#endregion

3调用扩展方法

a 添加扩展记录

  //btn  添加扩展记录
XDataClass PipeXdataClass = new XDataClass(Enum_XRcordName.pipe_whlkx.ToString());
ObjectId selectedObjId = ObjectId.Null;
private void btnAddXData_Click(object sender, EventArgs e)
{
if (CheckValue() == false)
{
return;
}
_instance.Hide();
Document doc = AcadApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityResult entityResult = ed.GetEntity("\n请选择一个多段线对象");//单个拾取对象
if (entityResult.Status != PromptStatus.OK)
{
_instance.Show();
return;
}
GetDataFromControls(PipeXdataClass);//私有函数,将控件中的数据填充到实体类中
//获取对象的ID
ObjectId objId = entityResult.ObjectId;
bool result = false;
using (DocumentLock docLock = doc.LockDocument())
using (Transaction trans = db.TransactionManager.StartTransaction())
{
//将xdataCalss类型的数据转换成一个typevalue型的列表
TypedValueList values = XDataClass.ClassToTypeValueList(PipeXdataClass);
result = objId.AddXRecordToObj(PipeXdataClass.XRecordName, values);
trans.Commit();
}
if (result)
{
ed.WriteMessage("\n对象的扩展数据添加成功!");
}
else
{
ed.WriteMessage("\n对象已经有扩展数据");
}
_instance.Show();
}

b 读取扩展记录

 //btn 读取扩展记录
private void btnReadXData_Click(object sender, EventArgs e)
{
_instance.Hide();
ClearContent();//清空控件中的内容
Document doc = AcadApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
//开始事务处理
using (DocumentLock docLock = doc.LockDocument())
using (Transaction trans = db.TransactionManager.StartTransaction())
{
PromptEntityResult entityResult = ed.GetEntity("\n请选择一个对象");//拾取单个对象
if (entityResult.Status != PromptStatus.OK)
{
ed.WriteMessage("\n取消了选择");
_instance.Show();
return;
}
//获取对象的ID
ObjectId objId = entityResult.ObjectId;
TypedValueList list = objId.GetObjXrecord(PipeXdataClass.XRecordName);
if (list is null)
{
ed.WriteMessage("\n该对象没有扩展记录");
_instance.Show();
return;
}
if (list.Count <= )
{
ed.WriteMessage("\n有扩展记录,但是记录为空");
_instance.Show();
return;
}
else
{
PipeXdataClass = XDataClass.TypeValueListToClass(list);
SetDataToControls(PipeXdataClass);//向控件中填充数据
ed.WriteMessage("\n对象扩展数据读取成功");
selectedObjId = objId;
}
}
_instance.Show();
}

c 删除扩展记录

         //btn 删除
private void btnDeleteXData_Click(object sender, EventArgs e)
{
_instance.Hide();
Document doc = AcadApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
//开始事务处理
using (DocumentLock docLock = doc.LockDocument())
using (Transaction trans = db.TransactionManager.StartTransaction())
{
PromptSelectionResult ss1 = ed.GetSelection();//框选对象
if (ss1.Status != PromptStatus.OK)
{
ed.WriteMessage("\n取消了选择");
_instance.Show();
return;
}
//获取对象的ID
List<ObjectId> listObjIds = ss1.Value.GetObjectIds().ToList();
int count = ;
listObjIds.ForEach(objId =>
{
if (objId.DeleteObjExtensionDictionary())
{
ed.WriteMessage("\n删除成功");
count++;
}
});
//ObjectId objId = entityResult.ObjectId;
//2018年4月7日09:50:35,经验证,必须先删除扩展字典下的所有的扩展记录,才能删除对象的扩展字典
//否则会出现错误:eContainerNotEmpty ,容器不为空
//objId.DelObjAllXrecords();
//objId.DeleteObjExtensionDictionary();
trans.Commit();
ed.WriteMessage("\n操作完成,总共删除{0}个扩展记录", count);
}
_instance.Show();
}

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

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

AutoCAD中的扩展字典及扩展记录(C#)

AutoCAD中的扩展字典及扩展记录(C#)的更多相关文章

  1. 在 Windows Azure 网站中进行纵向扩展和横向扩展

    编辑人员注释:本文章由 Windows Azure 网站团队的项目经理 Byron Tardif 撰写. 当您开始一个新的 Web 项目,或者刚刚开始开发一般的网站和应用程序时,您可能希望从小处着手. ...

  2. Memcache服务器端&plus;Redis服务器端&plus;PHP Memcache扩展&plus;PHP Memcached扩展&plus;PHP Redis扩展&plus;MemAdmin Memcache管理工具&plus;一些概念(更新中)

    Memcache和Redis因为操作简单,是我们常用的服务器数据缓存系统,以下文字仅作备忘记录,部份转载至网络. 一.定义 1.Memcache Memcache是一个高性能的分布式的内存对象缓存系统 ...

  3. 学习PHP中的高精度计时器HRTime扩展

    不知道大家还记得在学校的时候体育测试时老师带的秒表吗?当枪声想起时,我们开始跑步,这时秒表启动,当我们跑过终点后,老师会按下按扭记录我们的成绩,这就是一个典型的定时器的应用.今天我们要学习的内容其实就 ...

  4. 如何去掉drwxr-xr-x&commat;中的&commat;符号Linux文件扩展信息

    如何去掉drwxr-xr-x@中的@符号Linux文件扩展信息ls -lart drwxrwxrwx@ 10 rlanffy staff 340B 3 6 2015 files-rwxrwxrwx@ ...

  5. Shell编程-03-Shell中的特殊变量和扩展变量

    目录 特殊变量 变量扩展 特殊变量     在Shell中的特殊变量主要分别两种位置参数变量.状态变量两种. 位置参数变量     Shell中的位置参数变量主要是指$0.$1.$#等,主要用于从命令 ...

  6. 八、collection系列-----计数器、有序字典、默认字典、可命名元组、双向队列、单向队列一&period;计数器(对字典的扩展)

    一.计数器(对字典的扩展) 有如下一个字典: dic = {'k1':123,'k2':123,'k3':12} 统计12出现的次数,123出现的次数   1.统计出现次数 >>> ...

  7. PHP中DirectIO直操作文件扩展的使用

    关于 PHP 的文件操作,我们也将是通过一系列的文章来进行学习.今天我们先学习的是一个很少人使用过,甚至很多人根本不知道的扩展,它与我们日常的文件操作有些许的不同.不过这些差别并不是我们肉眼所能直观看 ...

  8. PHP中非常好玩的Calendar扩展学习

    为什么说这个 Calendar 扩展很好玩呢?因为你基本用不到它!这个扩展是一套关于日期历法的扩展,但是对于我们来说,它没有农历的相关操作,所以对于我们中国人来说这个扩展并没有什么实际的作用.不过这并 ...

  9. 理解水平扩展和垂直扩展 (转载 http&colon;&sol;&sol;yunjiechao-163-com&period;iteye&period;com&sol;blog&sol;2126981)

      当一个开发人员提升计算机系统负荷时,通常会考虑两种方式垂直扩展和水平扩展.选用哪种策略主要依赖于要解决的问题 以及系统资源的限制.在这篇文章中我们将讲述这两种策略并讨论每种策越的优缺点.如果你已经 ...

随机推荐

  1. MWeb 2&period;0 测试版可以下载啦,这次是公开测试,感兴趣的朋友可以试试

    2.0 版是 MWeb 发布以来,最重要的一个版本.MWeb 自去年一月份发布以来,获得了很多朋友的建议,在此非常感谢!没有你们,2.0 版可能就不能出来!然后再次感谢 Producter: http ...

  2. Abp公共连接和事务管理方法

    Conection 和事务管理在使用数据库的应用中是一个最重要的概念.当你打开一个连接,开始一个事务,如何来处理这些连接等等. 您也许知道,.NET使用了连接池.所以,创建一个连接实际上是从连接池里得 ...

  3. wpf 将Style应用到 ListView 中的 ListViewItem 元素

    例: 为每个条目元素设置右键菜单 1. 新建右键菜单元素和样式元素 注意: 同时设置样式元素的 TargetType 属性和 x:Key 属性, 将样式元素限定为应用于 ListViewItem 类型 ...

  4. OSGI&period;NET 学习笔记--应用篇

    关于osgi.net ,想必大家也听说过,以下是自己在学习osgi.net 过程中整理出来的内容,供大家学习参与使用. 1.  OSGI.NET 与UIOSP OSGi是Open Service Ga ...

  5. 在windows7中使用计划任务命令SCHTASKS查询计划任务失败的解决方案

    造成这种原因是因为编码问题: 因此需要修改编码:chcp schtasks.exe /query 会报错     错误: 无法加载列资源. 修改编码为936为436就可以允许啦,但是中文不不能显示啦. ...

  6. uva 10916 Factstone Benchmark(对数函数的活用)

    Factstone Benchmark Amtel has announced that it will release a 128-bit computer chip by 2010, a 256- ...

  7. classpath and path&period;

    simply talk about the <path> and the <classpath> in java development. when the <path& ...

  8. JavaScript基础知识----document对象

    对象属性document.title                 //设置文档标题等价于HTML的<title>标签document.bgColor               //设 ...

  9. BZOJ 1324&colon; Exca王者之剑

    1324: Exca王者之剑 Description Input 第一行给出数字N,M代表行列数.N,M均小于等于100 下面N行M列用于描述数字矩阵 Output 输出最多可以拿到多少块宝石 Sam ...

  10. 程序员网站开发时应该注意的SEO问题

    一.链接的统一性 搜索引擎排名最主要的因素就是网站内容和链接,假如网站内部链接不一致,在很大程度上直接影响着网站在搜索引擎中的排名.例如彩票专营店导航栏中的“首页”链接,程序员在开发时可能会有以下几种 ...