【转】CAD 二次开发--属性块 Block和BlockReference
1、属性块的定义
属性块是有构成的实体和附加信息(属性)组成的,属性块中块的定义与简单块中块的定义一样,而属性的定义主要是通过属性的AttributeDefinition类的有关属性和函数来实现的。具体实现有:
a 、AttributeDefinition类的实例并设置对象的属性值;
b、由于块的属性定义也可以看做是块中的实体,可以通过块表记录类的成员函数AppendEntity将属性定义附加到块中。
其中,属性定义的属性值主要有:
文字的插入点、高度、旋转角度、对齐方式和宽度;
属性的默认值;
属性的模式,如不可见方式Invisible、常量方式Constant、验证方式Verify、预置方式Preset;
属性标签名。
/// <summary> /// 块添加属性 /// </summary> /// <param name="blockId"></param> /// <param name="atts"></param> public static void AddAttsToBlocks(this ObjectId blockId, List<AttributeDefinition> atts) { Database db = blockId.Database;//获取数据库对象 BlockTableRecord btr = blockId.GetObject(OpenMode.ForWrite) as BlockTableRecord; foreach (AttributeDefinition att in atts) { btr.AppendEntity(att); db.TransactionManager.AddNewlyCreatedDBObject(att, true); } btr.DowngradeOpen(); } public static void AddAttsToBlocks(this ObjectId blockId, params AttributeDefinition[] atts) { blockId.AddAttsToBlocks(atts.ToList()); }
属性块的定义
2、插入属性块
块参照中的属性实体由DatabaseServices命名空间中的AttibuteReference类表示,它其实是一个单行文本对象,由DBText类派生。为块参照添加书体的步骤如下:
1)打开块参照所属的块表记录对象;
2)对块表记录中的实体进行循环遍历,如果实体是属性定义的对象,则根据它的标识为块参照属性对象设置属性值;
3)获取块参照对象的属性集合对象来为块参照添加新创建的属性参照对象。属性集合对象由BlockReference的AttributeCollection 属性标识,调用它的AppendAttribute函数就可以完成块参照的属性添加。
插入带属性的块参照
/// <summary> /// 插入带属性的参照快 /// </summary> /// <param name="spaceId">空间的ID</param> /// <param name="layer">块要加入的图层名</param> /// <param name="blockName">快参照所属的快名</param> /// <param name="postion">插入点</param> /// <param name="scale">缩放比例</param> /// <param name="rotateAngle">旋转角度</param> /// <param name="attNameValues">属性名称与取值</param> /// <returns></returns> public static ObjectId InsertBlockrefence(this ObjectId spaceId, string layer, string blockName, Point3d postion, Scale3d scale, double rotateAngle, Dictionary<string, string> attNameValues) { // 获取数据库对象 Database db = spaceId.Database; //以读的方式打开块表 BlockTable bt = db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable; //如果没有blockName d的块,则程序返回 if (!bt.Has(blockName)) return ObjectId.Null;//如果没有blockName的块,程序返回 //以写的模式打开空间 BlockTableRecord space = (BlockTableRecord)spaceId.GetObject(OpenMode.ForWrite); //获取块表的记录ID ObjectId btrId = bt[blockName]; //打开块表记录 BlockTableRecord record = btrId.GetObject(OpenMode.ForRead) as BlockTableRecord; //创建一个快参照并设置插入点 BlockReference br = new BlockReference(postion, bt[blockName]); br.ScaleFactors = scale; br.Layer = layer; br.Rotation = rotateAngle; space.AppendEntity(br); //判断块表记录是否包含属性定义 if (record.HasAttributeDefinitions) { //若包含,则遍历属性定义 foreach (ObjectId id in record) { //检查是否是属性定义 AttributeDefinition attDef = id.GetObject(OpenMode.ForRead) as AttributeDefinition; if (attDef != null) { //创建一个新的属性对象 AttributeReference attribute = new AttributeReference(); //从属性定义获取属性对象的对象特性 attribute.SetAttributeFromBlock(attDef, br.BlockTransform); attribute.Rotation = attDef.Rotation; attribute.Position = attDef.Position.TransformBy(br.BlockTransform); attribute.AdjustAlignment(db); //判断是否包含指定的属性名称 if (attNameValues.ContainsKey(attDef.Tag.ToUpper())) { //设置属性值 attribute.TextString = attNameValues[attDef.Tag.ToUpper()].ToString(); } // 向块参照添加属性对象 br.AttributeCollection.AppendAttribute(attribute); db.TransactionManager.AddNewlyCreatedDBObject(attribute, true); } } } db.TransactionManager.AddNewlyCreatedDBObject(br, true); return br.ObjectId;//返回添加的快参照的ID }
更新块参照
/// <summary> /// 更新属性名称与取值 /// </summary> /// <param name="blockRefId"></param> /// <param name="attNameValues"></param> public static void UpdateAttributesInBlock(this ObjectId blockRefId, Dictionary<string, string> attNameValues) { BlockReference blockRef = blockRefId.GetObject(OpenMode.ForRead) as BlockReference; if (blockRef != null) { foreach (ObjectId id in blockRef.AttributeCollection) { AttributeReference attref = id.GetObject(OpenMode.ForRead) as AttributeReference; if (attNameValues.ContainsKey(attref.Tag.ToUpper())) { attref.UpgradeOpen(); //设置属性值 attref.TextString = attNameValues[attref.Tag.ToUpper()].ToString(); attref.DowngradeOpen(); } } } }