using connor_zwcadm.dialog; using connor_zwcadm.model; using connor_zwcadm.util; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using ZwSoft.ZwCAD.ApplicationServices; using ZwSoft.ZwCAD.DatabaseServices; using ZwSoft.ZwCAD.EditorInput; namespace connor_zwcadm.commands { public class SyncTitleCommand : AbstractCADCommand { private KBackgroundWorker bgWorker { get; } public TCUtil TCUtil { get; } public SyncTitleCommand(Document doc):base(doc.Name) { bgWorker = new KBackgroundWorker(); bgWorker.backgroundWorker.DoWork += DoSync; TCUtil = new TCUtil(bgWorker); Test(doc, TCUtil); } public void DoSync(object sender, DoWorkEventArgs e) { bgWorker.Progress("初始化", "", 0); //读取图纸数据 bgWorker.Progress("读取图纸数据", 20); TCData titleData = KCADUtil.ReadDocData(false, TCUtil); Dictionary cadProps = TCUtil.ReadTCData(titleData); //更新图纸数据 bgWorker.Progress("更新图纸数据", 80); bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate { KCADUtil.WriteTitle(cadProps); // using (DocumentLock docLoc = doc.LockDocument()) { // // CADUtil.UpdateBlockProperty(doc.Database, titleData.BlockName, cadProps, IsMechanical, doc.Name); //} })); KUtil.Log("更新完成"); bgWorker.Progress("更新完成", "", 100); System.Threading.Thread.Sleep(800); } protected override void InitCommand() { } protected override void ExecuteCommand() { bgWorker.Start(null); } public static string Test(Document doc, TCUtil tcUtil) { // 1. 基础检查与路径处理 if (doc == null) { throw new Exception("图纸不能为null"); } string cadPath = doc.Name; KUtil.Log("转PDF: " + cadPath); string path = cadPath.Substring(0, cadPath.Length - 4) + ".pdf"; KUtil.Log("PDF路径:" + path); Database db = doc.Database; Editor ed = doc.Editor; // 获取编辑器用于输出消息(可选) string prefName = KMain.PREF_PROP_CONFIG_PREFIX + "力邦更改栏"; string[] prefVals = tcUtil.GetPrefValues(prefName); KUtil.Log("读取同步配置:" + prefName); int len = prefVals == null ? 0 : prefVals.Length; List res = new List(); for (int i = 0; i < len; i++) { string config = prefVals[i]; int ind = config.IndexOf('='); if (ind <= 0) { continue; } // KUtil.Log(">> "+config); string tcConfig = config.Substring(0, ind); string cadConfig = config.Substring(ind + 1); PropertyInfo info = PropertyInfo.parse(cadConfig, tcConfig); if (info == null) { KUtil.Log("无效配置: " + config); continue; } KUtil.Log("info: " + info.TcPropName); KUtil.Log("info: " + info.Location); KUtil.Log("info: " + info.CadPropName); res.Add(info); } Dictionary propMap = new Dictionary(); string th = ""; string bb = ""; using (Transaction tran = db.TransactionManager.StartTransaction()) { BlockTable blt = tran.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord bltr = tran.GetObject(db.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord; foreach (ObjectId item in bltr) { // 先以只读方式打开,提高性能 Entity ent = tran.GetObject(item, OpenMode.ForRead) as Entity; // 优化判断:直接使用 is 关键字,比 GetType().Name 更安全高效 if (ent is BlockReference bref) { if (bref.Name.Contains("更改栏")) { if (bref.AttributeCollection.Count > 0) { foreach (ObjectId attId in bref.AttributeCollection) { AttributeReference aRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference; if (aRef != null) { KUtil.Put(propMap, aRef.Tag, aRef.TextString); } } } } if (bref.Name.Contains("标题栏")) { if (bref.AttributeCollection.Count > 0) { foreach (ObjectId attId in bref.AttributeCollection) { AttributeReference aRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference; if (aRef != null) { if (aRef.Tag == "图号") { th = aRef.TextString; } else if (aRef.Tag == "版本") { bb = aRef.TextString; } } } } } } } } KUtil.Log("--------------"+KUtil.PrintDictionary(propMap)); TCData titleData = TCData.Parse(res, propMap); KUtil.Log("1"); Dictionary cadProps = tcUtil.ReadTCData2(titleData,th,bb); KUtil.Log("--------------1" + KUtil.PrintDictionary(cadProps)); using (Transaction tran = db.TransactionManager.StartTransaction()) { KUtil.Log("3. 开始事务"); BlockTable blt = tran.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; KUtil.Log("4. 获取块表"); // 注意:这里只遍历了当前空间 (CurrentSpaceId)。 // 如果标题栏在布局(Layout)中而当前在模型空间,可能遍历不到。 // 如果需要遍历所有布局,逻辑需要扩展(见下方提示)。 BlockTableRecord bltr = tran.GetObject(db.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord; KUtil.Log("5. 开始遍历实体"); foreach (ObjectId item in bltr) { // 先以只读方式打开,提高性能 Entity ent = tran.GetObject(item, OpenMode.ForRead) as Entity; // 优化判断:直接使用 is 关键字,比 GetType().Name 更安全高效 if (ent is BlockReference bref) { if (bref.Name.Contains("更改栏")) { KUtil.Log("发现块引用:" + bref.Name); if (bref.AttributeCollection.Count > 0) { // 遍历属性集合 foreach (ObjectId attId in bref.AttributeCollection) { // 先以只读方式打开属性 AttributeReference aRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference; if (aRef != null) { foreach (KeyValuePair item2 in cadProps) { string key = item2.Key; // 属性标签 (Tag),例如 "PROJECT_NAME" string value = item2.Value; // 属性值 (TextString),例如 "某某大厦项目" // 【核心逻辑】检查 Tag 是否为 "编制" // 注意:Tag 区分大小写,请确认 CAD 中该属性的 Tag 确实是 "编制" // 有时可能是 "DESIGNER", "DRAWN_BY" 等,如果不确定可以先打印 aRef.Tag 看看 if (aRef.Tag.Equals(key)) { // 【关键步骤】升级为写模式,否则无法赋值 aRef.UpgradeOpen(); // 设置新值 aRef.TextString = value; KUtil.Log($"已修改块 '{bref.Name}' ======: {value}"); // 如果只需要修改第一个找到的,可以在这里 break; // 如果要修改所有符合条件的块,则继续循环 } } } } } } } } // 提交事务,保存修改 tran.Commit(); KUtil.Log("事务已提交,属性修改生效"); } KUtil.Log("转换PDF完成(属性已预设置)"); return path; } } }