Cad 反应器 cad c#二次开发

        在 AutoCAD C# 二次开发中,`DocumentCollectionEventHandler` 是一个委托(delegate),用于处理与 AutoCAD 文档集合(DocumentCollection)相关的事件。它属于 AutoCAD .NET API 的事件处理机制,本质上是一种**反应器(Reactor)模式**的实现,用于响应文档生命周期事件(如创建、激活、销毁文档等)。

 本例为每激活一个文档,当前文档画一个圆。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
[assembly:CommandClass(typeof(IfoxDemo.DEMO))]

namespace IfoxDemo
{

    public class DEMO

    {
        [CommandMethod("xx")]
        public void CreatExcel()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            ed.WriteMessage("\n开始批量提取块属性");
        }
    }

    public class DocumentEventReactor

    {
        public DocumentEventReactor()// 初始化时订阅事件
        {
            DocumentCollection docCol = Application.DocumentManager;
            docCol.DocumentActivated += OnDocumentActivated;
           
        }
        // 订阅事件(仅允许调用一次)
        public void Subscribe()
        {
            DocumentCollection docCol = Application.DocumentManager;
            docCol.DocumentActivated -= OnDocumentActivated; // 避免重复订阅
            docCol.DocumentActivated += OnDocumentActivated;
        }
        public void Unsubscribe() // 清理时取消订阅(重要!)
        {
            DocumentCollection docCol = Application.DocumentManager;
            docCol.DocumentActivated -= OnDocumentActivated;
        }
        // 文档激活事件处理
        public void OnDocumentActivated(object sender, DocumentCollectionEventArgs e)
        {
            Document activeDoc = e.Document;
            Editor ed = activeDoc.Editor;
            Database db = activeDoc.Database;
            // 获取文档名称(不含路径)
            string docName = System.IO.Path.GetFileName(activeDoc.Name);
            // 在命令行显示提示
            ed.WriteMessage($"\n切换到文档: {docName} | 事件类型: {e.GetType().Name}");
            // 示例扩展操作:检查文档是否只读
            if (activeDoc.IsReadOnly) ed.WriteMessage("\n警告:当前文档为只读模式!");//
                                                                         // 锁定文档上下文(确保操作在正确文档中执行)
            using (DocumentLock docLock = activeDoc.LockDocument())
            {
                Circle c = new Circle(new Point3d(0, 0, 0), Vector3d.ZAxis, 5.0);
                c.ColorIndex = 1; // 设置颜色索引
                Application.DocumentManager.MdiActiveDocument.Database.AddEntityToModeSpace(c); // 添加圆到模型空间
                Application.DocumentManager.MdiActiveDocument.Editor.ZoomExtents(); // 缩放到适合视图  
            }
            }

    }
    // 在插件入口初始化

    //public class PluginCommands : IExtensionApplication

    //{

    //    private static DocumentEventReactor _reactor;



    //    public void Initialize()

    //    {

    //        _reactor = new DocumentEventReactor();

    //        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(

    //          "\n文档事件反应器已启动");

    //    }



    //    public void Terminate()

    //    {

    //        _reactor?.Unsubscribe();

    //    }

    //}
}

他常用事件处理示例:

 响应文档创建事件

Application.DocumentManager.DocumentCreated += (sender, e) => 

{

    Editor ed = e.Document.Editor;

    ed.WriteMessage($"\n新文档已创建: {e.Document.Name}");

};

```

#### 响应文档关闭事件

```csharp

Application.DocumentManager.DocumentToBeDestroyed += (sender, e) => 

{

    // 保存自定义数据到外部文件

    string backupPath = $"C:\\Backups\\{e.Document.Name}.settings";

    SaveCustomData(e.Document, backupPath);

};

```

通过合理利用 `DocumentCollectionEventHandler`,您可以构建响应 AutoCAD 文档环境变化的智能插件,显著提升用户体验和自动化水平。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
[assembly:CommandClass(typeof(IfoxDemo.DEMO))]

namespace IfoxDemo
{

    public class DEMO

    {
        [CommandMethod("xx")]
        public void CreatExcel()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            ed.WriteMessage("\n开始批量提取块属性");
        }
    }

    public  class DocumentEventReactor

    {
        public static void DocumentEventReactor1()// 初始化时订阅事件
        {
            DocumentCollection docCol = Application.DocumentManager;
            docCol.DocumentActivated += OnDocumentActivated;
            // 也可以订阅其他事件,如 DocumentCreated、DocumentToBeDestroyed 等
            docCol.DocumentToBeDeactivated += onDocumentToBeDeactivated; // 这里为了示例使用同一处理方法,实际可分开处理不同事件
            docCol.DocumentToBeDestroyed += onDocumentToBeDeactivated; // 这里为了示例使用同一处理方法,实际可分开处理不同事件
        }
        // 订阅事件(仅允许调用一次)
        public static void Subscribe()
        {
            DocumentCollection docCol = Application.DocumentManager;
            docCol.DocumentActivated -= OnDocumentActivated; // 避免重复订阅
            docCol.DocumentActivated += OnDocumentActivated;
        }
        public static void Unsubscribe() // 清理时取消订阅(重要!)
        {
            DocumentCollection docCol = Application.DocumentManager;
            docCol.DocumentActivated -= OnDocumentActivated;
        }
        // 文档激活事件处理
        public static void OnDocumentActivated(object sender, DocumentCollectionEventArgs e)
        {
            try
            {
                DocumentCollection dc = sender as DocumentCollection;
                // if (dc == null) return; // 确保 sender 是 DocumentCollection
                // 先取消旧订阅,避免重复
                dc.MdiActiveDocument.ImpliedSelectionChanged -= Doc_ImpliedSelectionChanged;
                dc.MdiActiveDocument.ImpliedSelectionChanged += Doc_ImpliedSelectionChanged; // 订阅 ImpliedSelectionChanged 事件
            }
            catch (Exception)
            {
                throw;
            }

            Document activeDoc = e.Document;
            Editor ed = activeDoc.Editor;
            Database db = activeDoc.Database;
            // 获取文档名称(不含路径)
            string docName = System.IO.Path.GetFileName(activeDoc.Name);
            // 在命令行显示提示
            ed.WriteMessage($"\n切换到文档: {docName} | 事件类型: {e.GetType().Name}");
            // 示例扩展操作:检查文档是否只读
            if (activeDoc.IsReadOnly) ed.WriteMessage("\n警告:当前文档为只读模式!");//
                                                                         // 锁定文档上下文(确保操作在正确文档中执行)
            using (DocumentLock docLock = activeDoc.LockDocument())
            {
                Circle c = new Circle(new Point3d(0, 0, 0), Vector3d.ZAxis, 5.0);
                c.ColorIndex = 1; // 设置颜色索引
                Application.DocumentManager.MdiActiveDocument.Database.AddEntityToModeSpace(c); // 添加圆到模型空间
                                                                                                // Application.DocumentManager.MdiActiveDocument.Editor.ZoomExtents(); // 缩放到适合视图  
            }

        }
        public static void onDocumentToBeDeactivated(object sender, DocumentCollectionEventArgs e)
        {
            try
            {
                DocumentCollection dc = sender as DocumentCollection;
                // if (dc == null) return; // 确保 sender 是 DocumentCollection
                dc.MdiActiveDocument.ImpliedSelectionChanged -= Doc_ImpliedSelectionChanged; // 订阅 ImpliedSelectionChanged 事件
            }
            catch (Exception)
            {
                throw;
            }
        }
        // 文档隐含选择集变化事件处理
        public static void Doc_ImpliedSelectionChanged(object sender, EventArgs e)
        {   
            Document doc = Application.DocumentManager.MdiActiveDocument; 
            using (DocumentLock dl = doc.LockDocument())
            {
                Editor ed = doc.Editor;
             
                ed.WriteMessage("\nImpliedSelectionChanged 事件触发!");
                // 获取当前选择集
                var psr = ed.SelectImplied();
                if (psr.Status != PromptStatus.OK) return;
                // 开启事务
                using (Transaction tr = doc.TransactionManager.StartTransaction())
                {
                    try
                    {
                        // 遍历选择集中的实体
                        foreach (ObjectId id in psr.Value.GetObjectIds())
                        {
                            // 通过事务获取实体(需指定OpenMode)
                            Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                            if (ent != null)
                            {
                                // 在命令行显示实体类型和ID
                                ed.WriteMessage($"\n实体类型: {ent.GetType().Name}, ID: {id}");
                                // 此处若需要修改实体,需将OpenMode设为ForWrite并在事务中提交
                            }
                        }
                        // 事务完成后提交(只读操作可省略,但建议显式调用以明确意图)
                        tr.Commit();
                    }
                    catch (Exception ex)
                    {
                        ed.WriteMessage($"\n事务处理错误: {ex.Message}");
                        tr.Abort(); // 异常时回滚事务
                    }

                    //try
                    //{
                    //    // 1. 创建空的选择集
                    //    SelectionSet emptySelection = null;
                    //    // 2. 使用SetImpliedSelection设置空选择集,清空当前选择
                    //    ed.SetImpliedSelection(emptySelection);
                    //    ed.WriteMessage("\n当前选择集已清空!");
                    //}
                    //catch (Exception ex)
                    //{
                    //    ed.WriteMessage($"\n清空选择集失败: {ex.Message}");
                    //}
                }
               
            }
        }
    }
    public class MyPlugin2 : IExtensionApplication
    {
        public void Initialize()
        {
            string str = "";//"输入命令\"ywxl\"执行 \n";
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\n插件已加载!(CAD插件定制:山水qq443440204)\n{str}\n");
            DocumentEventReactor.Subscribe(); // 订阅事件(仅一次)
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n文档事件反应器已启动");
        }
        public void Terminate()
        {
            //Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n结束");

            DocumentEventReactor.Unsubscribe();

        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山水CAD插件定制

你的鼓励是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值