提要:影響圖層顯示的主要有:
關閉 isOff
凍結 IsFrozen
圖層隱藏 isHidden
視口凍結 FreezeLayersInViewport
今天小博發現了一件事情,無論怎么用 IsHidden 都會出現報錯 eDuplicateRecordName

public class Command_Fuckcad { [CommandMethod("Hiddenlayer")] public void Hiddenlayer() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; using (Application.DocumentManager.MdiActiveDocument.LockDocument())//鎖文檔 { using (Transaction tr = db.TransactionManager.StartTransaction()) { LayerTable table = tr.GetObject(db.LayerTableId, OpenMode.ForWrite) as LayerTable; string ss = "Test"; LayerTableRecord layerName = null; if (table.Has(ss)) { foreach (var item in table) { layerName = tr.GetObject(item, OpenMode.ForRead) as LayerTableRecord; if (layerName.Name == ss) { layerName.UpgradeOpen(); layerName.IsHidden = true; layerName.DowngradeOpen(); break; } } } else { layerName = new LayerTableRecord { Name = ss, IsHidden = false }; table.Add(layerName); tr.AddNewlyCreatedDBObject(layerName, true); } table.DowngradeOpen(); table.Dispose(); tr.Commit(); } } } }
2008和2019測試都是
第一次遍歷,生成一個test圖層,
第二次遍歷,修改隱藏(相當於刪除了的感覺)
第三次遍歷,又生成了一個test圖層
第四次遍歷,修改隱藏報錯了
后來得到e大的幫助,說了一個很重要的問題,遍歷器上面沒有,那么我就去看了塊表,塊表上面有個參數是 IncludingHidden,
所以代碼要寫這句,層表才會顯示隱藏的圖層:(幾乎所有表都有這個隱藏?😏)
LayerTable table = tr.GetObject(db.LayerTableId, OpenMode.ForWrite) as LayerTable; table = table.IncludingHidden;
之后,我就發現了,報錯的原因:
第一次遍歷,生成一個test圖層,
第二次遍歷,修改隱藏(相當於把圖層改成了*Test的名字)
第三次遍歷,又生成了一個test圖層
第四次遍歷,修改隱藏,相當於吧test改成*test,因為第二遍的時候隱藏的已經有這個名字了,就報錯了!
寫了個例子給大家抄: 嘗試注釋掉打開隱藏那個,反復執行一下fuckcad命令

public class Command_Fuckcad { [CommandMethod("fuckcad")] public void Fuckcad() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; using (Application.DocumentManager.MdiActiveDocument.LockDocument())//鎖文檔 { using (Transaction tr = db.TransactionManager.StartTransaction()) { LayerTable table = tr.GetObject(db.LayerTableId, OpenMode.ForWrite) as LayerTable; table = table.IncludingHidden;//層表包含隱藏的,全部顯示出來 string layerName = "Test"; LayerTableRecord ltr = null; if (!table.Has(layerName)) { ltr = new LayerTableRecord { Name = layerName }; table.Add(ltr); tr.AddNewlyCreatedDBObject(ltr, true); } switch (LayerHiddenOn(tr, db, layerName)) { case LayerHiddenError.OK: ed.WriteMessage("\n更改隱藏成功"); break; case LayerHiddenError.No: ed.WriteMessage("\n不含有圖層,所以沒得更改隱藏"); break; case LayerHiddenError.ErrorHaveStarsLayer: ed.WriteMessage("\n已有帶*圖層,不能隱藏"); break; case LayerHiddenError.ErrorNotStarsLayer: ed.WriteMessage("\n已有不帶*圖層,不能取消隱藏");//這句始終不會執行 break; } switch (LayerHiddenOff(tr, db, layerName)) { case LayerHiddenError.OK: ed.WriteMessage("\n更改隱藏成功"); break; case LayerHiddenError.No: ed.WriteMessage("\n不含有圖層,所以沒得更改隱藏"); break; case LayerHiddenError.ErrorHaveStarsLayer: ed.WriteMessage("\n已有帶*圖層,不能隱藏");//這句始終不會執行 break; case LayerHiddenError.ErrorNotStarsLayer: ed.WriteMessage("\n已有不帶*圖層,不能取消隱藏"); break; } tr.Commit(); } } } }

/// <summary> /// 是否成功修改的標記 /// </summary> public enum LayerHiddenError { /// <summary> /// 成功更改隱藏 /// </summary> OK, /// <summary> /// 不含有圖層,所以沒得更改隱藏 /// </summary> No, /// <summary> /// 已有帶*圖層,不能隱藏 /// </summary> ErrorHaveStarsLayer, /// <summary> /// 已有不帶*圖層,不能取消隱藏 /// </summary> ErrorNotStarsLayer, } /// <summary> /// 取消隱藏 /// </summary> /// <param name="tr">事務</param> /// <param name="table">數據庫</param> /// <param name="layerName">不帶*的圖層名稱</param> /// <returns></returns> public static LayerHiddenError LayerHiddenOff(Transaction tr, Database db, string layerName) { LayerTable table = tr.GetObject(db.LayerTableId, OpenMode.ForWrite) as LayerTable; table = table.IncludingHidden;//層表包含隱藏的,全部顯示出來 if (!table.Has(layerName)) { string layerNameX = "*" + layerName; foreach (var item in table) { if (item.IsOk()) { var ltr = tr.GetObject(item, OpenMode.ForRead) as LayerTableRecord; if (ltr.Name == layerNameX) { ltr.IsHidden = false; return LayerHiddenError.OK; } } } return LayerHiddenError.No; } else { return LayerHiddenError.ErrorNotStarsLayer; } } /// <summary> /// 隱藏圖層 /// </summary> /// <param name="tr">事務</param> /// <param name="db">數據庫</param> /// <param name="layerName">不帶*的圖層名稱</param> /// <returns></returns> public static LayerHiddenError LayerHiddenOn(Transaction tr, Database db, string layerName) { LayerTable table = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable; table = table.IncludingHidden;//層表包含隱藏的,全部顯示出來 if (!table.Has("*" + layerName)) { foreach (var item in table) { if (item.IsOk()) { var ltr = tr.GetObject(item, OpenMode.ForWrite) as LayerTableRecord; if (ltr.Name == layerName) { ltr.IsHidden = true; //隱藏就是 "*" + layerName return LayerHiddenError.OK; } } } return LayerHiddenError.No; } else { return LayerHiddenError.ErrorHaveStarsLayer; } }
因為*號是保留關鍵字,普通用戶不給用的,大家要判斷層名的時候就要打開IncludingHidden 遍歷的時候同時判斷 "*"+layerName 和 layerName
普通cad用戶只能干着急,嘻嘻
e大還說了,把dwg存成dxf,然后用對比文件看,也能看到,並改......這貌似是給普通用戶的簡便修改方式?