通过ASP.NET Core API插入含BlockPlaceholder字段属性的动态块时避免执行ATTSYNC
通过ASP.NET Core API插入含BlockPlaceholder字段属性的动态块时避免执行ATTSYNC
太懂你这种崩溃的感觉了——两千多个动态块,手动跑ATTSYNC完全是不可行的死路!手动插入时属性能正常解析BlockPlaceholder字段显示内容,结果用代码插入后属性就“隐身”了,明明数据库里存在就是看不到。结合你给出的代码,我给你几个关键的调整点,应该能彻底解决这个问题:
关键修改步骤
1. 保留属性定义的原始字段表达式,别清空TextString
你代码里的attRef.TextString = "";会直接清空属性默认值里的BlockPlaceholder字段表达式,这就是属性不显示的核心原因之一!直接删掉这行,让SetAttributeFromBlock方法保留原属性定义里的字段内容。
2. 强制字段评估并同步显示
设置完字段后,不要只调用campo.Evaluate(),要调用属性引用的UpdateField(true)方法,强制AutoCAD解析字段并更新显示。
3. 局部同步单个块引用的属性,替代全局ATTSYNC
全局ATTSYNC效率极低,我们可以针对每个插入的块引用做局部属性同步,调用blkRef.SyncAttributes()就可以,只会同步当前块的属性,完全不影响其他块。
4. 通知图形数据库和编辑器刷新
插入完块和属性后,要告诉AutoCAD更新图形显示,避免缓存导致的不显示问题。
修改后的核心代码片段
把你原来的属性处理循环改成这样:
foreach (var attDef in attDefs) { var attRef = new AttributeReference(); attRef.SetAttributeFromBlock(attDef, blkRef.BlockTransform); // 删掉attRef.TextString = ""; 保留原字段表达式 if (camposAtributos.TryGetValue(attDef.Tag, out Field campo)) { attRef.SetField(campo); // 强制字段评估并同步显示 attRef.UpdateField(true); } else if (attDef.Tag == "HANDLE") { // 直接设置HANDLE属性值,不用清空原有内容 attRef.TextString = blkRef.Handle.ToString(); } // 将属性添加到块引用的属性集合 blkRef.AttributeCollection.AppendAttribute(attRef); trans.AddNewlyCreatedDBObject(attRef, true); } // 局部同步当前块引用的属性,替代全局ATTSYNC blkRef.SyncAttributes(); // 通知图形数据库更新块的图形信息 blkRef.RecordGraphicsModified(true);
额外的收尾处理
在事务提交后,强制编辑器刷新一次,确保所有插入的块属性都能立即显示:
trans.Commit(); // 刷新编辑器显示 ed.Regen();
这些调整的核心逻辑就是:保留动态块属性里的原始BlockPlaceholder字段表达式,针对单个块做局部属性同步,强制字段解析和图形刷新,完全不用依赖全局的ATTSYNC,效率和效果都能满足你两千多个块的需求。
内容来源于stack exchange




