The version I am using is CAD2020. I encountered the same problem in CAD2018 and CAD2019.
Scenario: I use the code to copy the block file I need from my block storage drawing to my target drawing project, and then modify the dynamic length and width attributes after inserting. The problem is that the in-block filling cannot be updated automatically. You need to manually open the block file, and then click to save the changes when closing. All blocks will be updated automatically.
public class TestCmd
{
[CommandMethod("TestCmd")]
public void Test()
{
try
{
HatchInDynamicBlock();
}
catch (System.Exception ex)
{
Trace.WriteLine(ex.Message + ex.StackTrace);
}
}
public void HatchInDynamicBlock()
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
ObjectId result = ObjectId.Null;
Point3d originPoint = new Point3d(0, 0, 0);
double resultWidth = 1.1;
double resultHeight = 2.2;
string blockName = "块状测试图案";
string blockDWGPath = @"C:\Users\Acer\Desktop\块测试图纸路径\块图纸.dwg";
ObjectId blockId = ObjectId.Null;
#region 拿到块的id
//开启事务处理
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
if (!bt.Has(blockName))
{
using (Database tempDB = new Database(false, false))
{
tempDB.ReadDwgFile(blockDWGPath, FileOpenMode.OpenForReadAndReadShare, true, null);//读取外部DWG到临时数据库
tempDB.CloseInput(true);
ObjectIdCollection ids = new ObjectIdCollection();//存放块OjbectId的集合
using (Transaction trans2 = tempDB.TransactionManager.StartTransaction())
{
BlockTable bt2 = trans2.GetObject(tempDB.BlockTableId, OpenMode.ForRead) as BlockTable;
ObjectId targetID = bt2[blockName];
ids.Add(targetID);
}
////复制临时数据库中的块到当前数据库的块表中
tempDB.WblockCloneObjects(ids, db.BlockTableId, new IdMapping(), DuplicateRecordCloning.Ignore, false);
}
}
blockId = bt[blockName];
}
catch (System.Exception ex)
{
Trace.WriteLine(ex.Message);
}
trans.Commit();
}
#endregion
#region 插入块
using(Transaction createTrans = doc.TransactionManager.StartTransaction())
{
//插入图块
BlockTable bt = createTrans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord curBtr = createTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
//Trace.WriteLine(blockId.ToString());
db.TransactionManager.QueueForGraphicsFlush();
using (BlockReference blockRef = new BlockReference(originPoint, blockId))
{
db.Regenmode = true;
result = curBtr.AppendEntity(blockRef);
createTrans.AddNewlyCreatedDBObject(blockRef, true);
}
createTrans.Commit();
}
#endregion
#region 修改动态快属性
using (Transaction trans2 = doc.TransactionManager.StartTransaction())
{
try
{
doc.TransactionManager.QueueForGraphicsFlush();
BlockReference blockRef = trans2.GetObject(result, OpenMode.ForWrite, true, true) as BlockReference;
BlockTableRecord btr = trans2.GetObject(blockRef.BlockTableRecord, OpenMode.ForWrite) as BlockTableRecord;
var blockDynamicProperty = blockRef.DynamicBlockReferencePropertyCollection;
List<DynamicBlockReferenceProperty> blockPropertyList = blockDynamicProperty.OfType<DynamicBlockReferenceProperty>().ToList();
blockPropertyList.FirstOrDefault(x => x.PropertyName.Equals("长度")).Value = resultHeight;
blockPropertyList.FirstOrDefault(x => x.PropertyName.Equals("宽度")).Value = resultWidth;
btr.UpdateAnonymousBlocks();
}
catch (System.Exception ex)
{
Trace.WriteLine(ex.Message);
}
trans2.Commit();
}
#endregion
}
}
Where Path is replaced by the downloaded block drawing file path。
I also provide the block drawing file I use to test, and I will occasionally encounter this kind of thing, especially when it comes to batch generation, I hope I can get your help
Your code could use some cleaning up, but the main problem is that you need to update the properties of the block reference, not the block table record. See this post for a sample. Note the section below. It uses a method called SetDynProps to set the properties of the BlockReference. Note that you don't need multiple transactions. You do it in the same transaction, where you already have a reference to the BlockReference.
using (var tr = db.TransactionManager.StartTransaction())
{
// insert the block reference and set its dynamic properties
var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
var br = new BlockReference(Point3d.Origin, btrId);
curSpace.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
SetDynProps(br, dynPropValues);
// create the solid 3d
CreateSweptSolid(ed, startPoint, endPoint, tr, curSpace, br);
tr.Commit();
}
Can't find what you're looking for? Ask the community or share your knowledge.