cad c#二次开发 图层封装 获取当前层

发布于:2025-08-07 ⋅ 阅读:(10) ⋅ 点赞:(0)
    public static class 图层助手
    {
        /// <summary>
        /// 将模型空间所有实体的图层修改为当前文档的当前图层
        /// </summary>
        /// <param name="doc">当前文档对象</param>
        /// <param name="editor">CAD编辑器对象(用于输出提示信息)</param>
        /// <returns>成功修改的实体数量</returns>
        public static int 改所有实体到当前图层(Document doc, Editor editor)
{
    int modifiedCount = 0;
    string currentLayer = ""; // 当前图层名称
    // 1. 获取当前图层名称(关键:从文档获取当前活动图层)
    try
    {
        //object clayerValue = doc.Database.Clayer;
        object clayerValue = Application.GetSystemVariable("CLAYER");
        currentLayer = clayerValue.ToString();
        if (string.IsNullOrEmpty(currentLayer))
        {
            currentLayer = "0"; // 默认图层名称
        }
    }
    catch (Exception ex)
    {
    }

    if (string.IsNullOrEmpty(currentLayer))
    {
        currentLayer = "0"; // 默认图层名称
    }

    using (Transaction trans = doc.TransactionManager.StartTransaction())
    {
        try
        {
            // 2. 打开模型空间块表记录(写模式,因为需要修改实体)
            BlockTable blockTable = trans.GetObject(
                doc.Database.BlockTableId, OpenMode.ForRead
            ) as BlockTable;
            BlockTableRecord modelSpace = trans.GetObject(
                blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite
            ) as BlockTableRecord;

            // 3. 遍历模型空间所有实体ID
            foreach (ObjectId entityId in modelSpace)
            {
                Entity entity = trans.GetObject(entityId, OpenMode.ForWrite) as Entity;
                if (entity == null || entity.IsErased) continue; // 跳过无效实体

                // 4. 执行图层修改(仅当当前图层不同时操作)
                if (entity.Layer != currentLayer)
                {
                    entity.Layer = currentLayer; // 直接赋值图层名称
                    modifiedCount++;
                }

                entity.Dispose(); // 显式释放实体(虽然事务结束会自动释放,但显式调用更安全)
            }

            trans.Commit(); // 提交事务
                            // editor.WriteMessage($"\n成功修改 {modifiedCount} 个实体的图层到【{currentLayer}】");
        }
        catch (System.Exception ex)
        {
            trans.Abort(); // 异常时回滚事务
            //editor.WriteMessage($"\n批量改图层失败:{ex.Message}");
        }
    }

    return modifiedCount;
}
        public static string 获取当前层(this Database db) 
        {
           Document doc = Application.DocumentManager.MdiActiveDocument;
            string currentLayer = ""; // 当前图层名称
                                      // 1. 获取当前图层名称(关键:从文档获取当前活动图层)
            try
            {
                //object clayerValue = doc.Database.Clayer;
                object clayerValue = Application.GetSystemVariable("CLAYER");
                currentLayer = clayerValue.ToString();
                if (string.IsNullOrEmpty(currentLayer))
                {
                    currentLayer = "0"; // 默认图层名称
                }
            }
            catch (Exception ex)
            {
            }

            if (string.IsNullOrEmpty(currentLayer))
            {
                currentLayer = "0"; // 默认图层名称
            }
            return currentLayer;
            #region
            //using (Transaction trans = doc.TransactionManager.StartTransaction())
            //{
            //    try
            //    {
            //        // 2. 打开模型空间块表记录(写模式,因为需要修改实体)
            //        BlockTable blockTable = trans.GetObject(
            //            doc.Database.BlockTableId, OpenMode.ForRead
            //        ) as BlockTable;
            //        BlockTableRecord modelSpace = trans.GetObject(
            //            blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite
            //        ) as BlockTableRecord;

            //        // 3. 遍历list实体ID
            //        ents.ForEach(ent =>
            //        {
            //            ent.Layer = currentLayer;
            //        }); // 直接赋值图层名称 
            //        trans.Commit(); // 提交事务
            //                        // editor.WriteMessage($"\n成功修改 {modifiedCount} 个实体的图层到【{currentLayer}】");
            //    }
            //    catch (System.Exception ex)
            //    {
            //        trans.Abort(); // 异常时回滚事务
            //                       //editor.WriteMessage($"\n批量改图层失败:{ex.Message}");
            //    }
            //}
            #endregion
        }

        /// <summary>
        /// 获取指定图层的颜色索引
        /// </summary>
        /// <param name="layerName">目标图层名称</param>
        /// <returns>图层的颜色索引(若不存在返回-1)</returns>
        public static int 获取图层颜色(this string layerName )
        {
            // 获取当前文档和数据库
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            // 使用事务保证数据库操作安全
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    // 打开图层表(只读模式)
                    LayerTable layerTable = tr.GetObject(
                        db.LayerTableId,
                        OpenMode.ForRead
                    ) as LayerTable;

                    // 检查图层是否存在
                    if (!layerTable.Has(layerName))
                    {
                        return 0; // 返回表示图层不存在
                    }

                    // 获取图层记录(只读模式)
                    ObjectId layerId = layerTable[layerName];
                    LayerTableRecord layer = tr.GetObject(
                        layerId,
                        OpenMode.ForRead
                    ) as LayerTableRecord;

                    // 返回颜色索引
                    return layer.Color.ColorIndex;
                }
                finally
                {
                    tr.Commit(); // 提交事务(只读操作仍需要提交)
                }
            }
        }

    }
 public static  class 图层助手1
 {

     public static void SetCurrentLayer(this Database db, Entity ent)
     {
         if (db == null||ent is null||ent.IsErased) return;
         try
         {
             using (Transaction tr = db.TransactionManager.StartTransaction())
             {
                 var getent = tr.GetObject(ent.ObjectId, OpenMode.ForWrite) as Entity;
                 //LayerTable layerTable = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
                 //var ltr = tr.GetObject(db.Clayer, OpenMode.ForRead) as LayerTableRecord;
                 //ent.Layer = ltr.Name;
                 getent.LayerId = db.Clayer;
                 tr.Commit();
             }
         }
         catch (Exception ex)
         {
             Z.WriteEX(ex);
         }
        

     }

     /// <summary>
     /// 将指定的图层设置为当前层
     /// </summary>
     /// <param name="db">数据库对象</param>
     /// <param name="layerName">图层名</param>
     /// <returns>如果设置成功,则返回ture</returns>
     public static bool SetCurrentLayer(this Database db, string layerName)
     {
         #region 前置校验(避免非法输入)
         if (string.IsNullOrEmpty(layerName))
             return false; // 图层名不能为空

         // 检查图层名是否包含AutoCAD禁止的特殊字符(如<、>、:等)
         if (layerName.IndexOfAny(new[] { '<', '>', ':', '"', '/', '\\', '|', '?', '*' }) != -1)
             return false;
         #endregion

         // 获取当前文档(确保在AutoCAD界面中运行)
         Document doc = Application.DocumentManager.MdiActiveDocument;
         if (doc == null) return false;

         // 启动事务(关键!保证数据库操作的原子性)
         using (Transaction tr = db.TransactionManager.StartTransaction())
         {
             try
             {
                 #region 步骤1:获取图层表(LayerTable)
                 // 以读模式打开图层表(所有图层的容器)
                 LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
                 if (lt == null) return false; // 图层表获取失败
                 #endregion

                 #region 步骤2:检查图层是否存在
                 if (!lt.Has(layerName))
                     return false; // 图层不存在
                 #endregion

                 #region 步骤3:获取目标图层ID
                 ObjectId targetLayerId = lt[layerName];
                 #endregion

                 #region 步骤4:判断是否已为当前图层(避免重复设置)
                 // 使用 LayerManager 获取当前图层ID(新版本推荐方式)
                 if (db.Clayer == targetLayerId)
                     return false; // 已是当前图层
                 #endregion

                 #region 步骤5:设置当前图层(新版本推荐方式)
                 db.Clayer = targetLayerId;
                 #endregion

                 tr.Commit(); // 提交事务(所有操作生效)
                 return true;
             }
             catch (Exception ex)
             {
                 tr.Abort(); // 异常时回滚事务
                 doc.Editor.WriteMessage($"\n设置当前图层失败:{ex.Message}");
                 return false;
             }
         }
     }
     public static string SetLayer(this Database db, Entity ent, string layname)
     {
         if (ent.Layer == layname) return layname;
         // Database db = HostApplicationServices.WorkingDatabase;
         Document mdiActiveDocument = Application.DocumentManager.MdiActiveDocument;
         using (Transaction transaction = db.TransactionManager.StartTransaction())
         {
             LayerTable layerTable = transaction.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
             if (!layerTable.Has(layname))
             {
                 LayerTableRecord layerTableRecord = new LayerTableRecord();
                 layerTableRecord.Color = Color.FromColorIndex(ColorMethod.ByAci, 0);
                 layerTableRecord.Name = layname;
                 layerTable.UpgradeOpen();
                 layerTable.Add(layerTableRecord);
                 transaction.AddNewlyCreatedDBObject(layerTableRecord, add: true);
             }
             //// 以只读方式打开块表   Open the Block table for read
             //BlockTable acBlkTbl = transaction.GetObject(db.BlockTableId,
             //                             OpenMode.ForRead) as BlockTable;

             //// 以写方式打开模型空间块表记录   Open the Block table record Model space for write
             //BlockTableRecord acBlkTblRec = transaction.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
             //                                OpenMode.ForWrite) as BlockTableRecord;
             //// 设置图层
             Entity entInTrans = transaction.GetObject(ent.ObjectId, OpenMode.ForWrite) as Entity;
             entInTrans.Layer = layname;

             ////acBlkTblRec.AppendEntity(ent);
             //transaction.AddNewlyCreatedDBObject(ent, true);

             // Save the changes and dispose of the transaction
             transaction.Commit();

         }

         return layname;
     }

     /// <summary>
     /// 添加图层
     /// </summary>
     /// <param name="db">图形数据库</param>
     /// <param name="layerName">图层名</param>
     /// <returns>AddLayerResult</returns>
     public static AddLayerResult AddLayer(this Database db, string layerName)
     {
         //声明AddLayerResult类型的数据,用户返回
         AddLayerResult res = new AddLayerResult();
         try
         {
             SymbolUtilityServices.ValidateSymbolName(layerName, false);
         }
         catch (Exception)
         {
             res.statuts = AddLayerStatuts.IllegalLayerName;
             return res;
         }

         using (Transaction trans = db.TransactionManager.StartTransaction())
         {
             //打开层表
             LayerTable lt = (LayerTable)trans.GetObject(db.LayerTableId, OpenMode.ForRead);
             //新建层表记录
             if (!lt.Has(layerName))
             {

                 LayerTableRecord ltr = new LayerTableRecord();
                 //判断要创建的图层名是否已经存在,不存在则创建
                 ltr.Name = layerName;
                 //升级层表打开权限
                 lt.UpgradeOpen();
                 lt.Add(ltr);
                 //降低层表打开权限
                 lt.DowngradeOpen();
                 trans.AddNewlyCreatedDBObject(ltr, true);
                 trans.Commit();
                 res.statuts = AddLayerStatuts.AddLayerOK;
                 res.layerName = layerName;
             }
             else
             {
                 res.statuts = AddLayerStatuts.LayerNameExist;
             }
         }
         return res;
     }
     public enum AddLayerStatuts
     {
         AddLayerOK,
         IllegalLayerName,
         LayerNameExist
     }
     //添加图层的返回值
     public struct AddLayerResult
     {
         public AddLayerStatuts statuts;
         public string layerName;
     }
     //修改图层属性的返回状态
     public enum ChangeLayerPropertyStatus
     {
         ChangeOK,
         LayerIsNotExist

     }

 }

CAD 二次开发、插件定制↓↓↓


网站公告

今日签到

点亮在社区的每一天
去签到