遇到一个口头机遇的答辩准备3(ai告诉的要点)

嘤嘤嘤,写了一堆。网页一卡都没了......,草稿里也找不到......以前会有定时保存的......可能修改不会有吧额......那就再开一个避免重蹈覆辙......续上面的(估计没有第一次漂亮了哎,就当再次复习了)


四、图元操作万能套路

创建 → new → AppendEntity → 提交

cs 复制代码
// 标准创建流程
Line line = new Line(p1, p2);       // 1. new 创建
tr.AddNewlyCreatedDBObject(line, true); // 2. 加入数据库
AppendEntity(line);                 // 3. 加入空间(可选写法)
tr.Commit();                        // 4. 提交

读取 → tr.GetObject(id, ForRead)

cs 复制代码
Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;

修改 → tr.GetObject(id,ForWrite) → 改属性 → 提交

cs 复制代码
Entity ent = tr.GetObject(id, OpenMode.ForWrite); // 必须写打开
ent.ColorIndex = 1;                               // 修改
tr.Commit();                                      // 提交

删除 → tr.GetObject(id,ForWrite) → ent.Erase() → 提交

cs 复制代码
Entity ent = tr.GetObject(id, OpenMode.ForWrite);
ent.Erase();             // 删除
tr.Commit();            // 提交

五、几何相关的

Point2d / Point3d 是结构体(Struct),不是类

cs 复制代码
Point3d a = new Point3d(10, 20, 30);
Point3d b = a; // 复制一份全新的
b.X = 999;     // 改 b
// a 依然是 10,20,30
// b 变成 999,20,30


Point2d p1 = new Point2d(0,0);
Point2d p2 = p1; // 复制值
p2.X = 100;
// p1 还是 (0,0)

顺便提一嘴:

官网看到带美元符号 的,不是付费的意思,是静态static的意思(在Matrix3d这里基本静态的是创建矩阵,非静态,实例的是操作已有矩阵)。

另外一般大写的是C#小写的是C++的,例如:GetDistanceTo和getDistanceTo

【创建】
cs 复制代码
Point2d p2 = new Point2d(x, y);
Point3d p3 = new Point3d(x, y, z);
Point3d org = Point3d.Origin; // (0,0,0)
【取值】
cs 复制代码
double x = p3.X;
double y = p3.Y;
double z = p3.Z;
【距离】
cs 复制代码
using Autodesk.AutoCAD.Geometry;

// 1. Point3d 点到点:只能用 DistanceTo
Point3d p1 = new Point3d(0,0,0);
Point3d p2 = new Point3d(10,0,0);
double distPoint = p1.DistanceTo(p2); // ✅ 编译通过
// double distError = p1.GetDistanceTo(p2); // ❌ 编译报错:Point3d无此方法

// 2. Curve2d 点到曲线:只能用 GetDistanceTo
Line2d line2d = new Line2d(new Point2d(0,0), new Point2d(10,0));
Point2d pt2d = new Point2d(5, 5);
double distCurve = line2d.GetDistanceTo(pt2d); // ✅ 编译通过
// double distCurveError = line2d.DistanceTo(pt2d); // ❌ 编译报错:Curve2d无此方法
方法名 作用
Point3d DistanceTo(Point3d) 点→点 直线距离
Point2d DistanceTo(Point2d) 点→点 直线距离
Curve2d GetDistanceTo(Point2d) 点→曲线 最短距离
Curve3d GetDistanceTo(Point3d) 点→曲线 最短距离
Curve2d GetDistanceTo(Curve2d) 曲线→曲线 距离
Curve3d GetDistanceTo(Curve3d) 曲线→曲线 距离
【运算】
cs 复制代码
Point3d p = p1 + p2;
Point3d p = p1 - p2;
Point3d p = p1 * 2;
Point3d p = p1 / 2;

Vector3d vec = p2 - p1; // 点-点=向量
Point3d p = p + vec;    // 点+向量=点
【2D ↔ 3D 互转】
cs 复制代码
Point2d p2 = p3.Convert2d();
Point3d p3 = p2.Convert3d();
【矩阵变换】
cs 复制代码
Point3d newP = p.TransformBy(matrix);
【相等判断】
cs 复制代码
bool eq = p1.IsEqualTo(p2, 0.001);
【常用小公式】
cs 复制代码
Point3d mid = p1 + (p2 - p1) * 0.5; // 中点

Vector3d dir = (p2 - p1).Normalize(); // 单位方向
Point3d newP = p1 + dir * 10;         // 沿方向走10

坐标:WCS 世界坐标系 为主

WCS 世界坐标系原点(0,0,0)永远在同一个位置;X向右,Y向上,Z垂直屏幕向外;永远不会被用户修改、移动、旋转。 (API拿到的、数据库存的,永远是WCS,代码只认WCS

UCS 用户坐标系 :人看着方便,界面显示给用户看;用户可以新建、旋转、移动、换视角。

**DCS显示坐标系/屏幕坐标系:**鼠标/屏幕交互,左上角是原点,往右 X+,往下 Y+(频频木像素,极少用)

旋转、矩阵变换用 Matrix3d

Matrix3d是一个"变形工具包(黑盒子)",他专门做:移动、旋转、缩放、镜像、斜切这5件事。

【固定模板】
cs 复制代码
// 1. 定义一个点
Point3d pt = new Point3d(10, 0, 0);

// 2. 创建变形矩阵(旋转/移动/缩放/镜像)
Matrix3d mat = Matrix3d.Rotation(...);

// 3. 应用变换 → 得到新点
Point3d newPt = pt.TransformBy(mat);

注意:

TransformBy 只会计算新的点,原来的点不变,不直接影响图纸显示;

(TransformBy 生成 Point3d 内存坐标,不生成 DBPoint)

Point3d 不是对象,是 struct(值类型,存在栈),不受GC管理;是内存里的点,他是数据坐标。

DBPoint 才是CAD图纸可见的,存在堆Heap,需要GC(DBPoint点、Line线、Polyline多边形、Circle圆......)

cs 复制代码
// 1. 只是坐标(看不见)
Point3d pt = new Point3d(10, 20, 0);

// 2. 真正画到图上(看得见)
DBPoint dbPt = new DBPoint(pt); 
【旋转】Matrix3d.Rotation(角度, Z轴, 中心点)
cs 复制代码
// 角度:弧度(Math.PI = 180°)
double angle = Math.PI / 2;   // 90度
Point3d basePoint = new Point3d(0,0,0);  // 旋转基点

// 构建旋转矩阵(绕 Z 轴 = 平面旋转)
Matrix3d matRot = Matrix3d.Rotation(angle, Vector3d.ZAxis, basePoint);

// 应用到点/实体
Point3d newPt = pt.TransformBy(matRot);
line.TransformBy(matRot);
【移动】Matrix3d.Rotation(角度, Z轴, 中心点)
cs 复制代码
Point3d fromPt = new Point3d(0,0,0);
Point3d toPt   = new Point3d(10,20,0);

// 移动矩阵:从 from → to
Matrix3d matMove = Matrix3d.Displacement(fromPt, toPt);

// 应用
ent.TransformBy(matMove);
【缩放】Matrix3d.Scaling(比例, Z轴, 中心点)
cs 复制代码
double scale = 2.0;  // 放大2倍
Point3d basePoint = new Point3d(0,0,0);

Matrix3d matScale = Matrix3d.Scaling(scale, Vector3d.ZAxis, basePoint);

ent.TransformBy(matScale);
【镜像】Matrix3d.Mirror(轴点1, 轴点2)
cs 复制代码
// 镜像轴:两点确定一条直线
Point3d p1 = new Point3d(0,0,0);
Point3d p2 = new Point3d(0,10,0);

Matrix3d matMirror = Matrix3d.Mirror(p1, p2);

ent.TransformBy(matMirror);
【组合变换-矩阵叠加】矩阵是右乘 → 右边先直线,左边后执行(A *B=先B后A)
cs 复制代码
Matrix3d mat1 = 旋转;
Matrix3d mat2 = 移动;

// 叠加:先旋转 → 再移动
Matrix3d finalMat = mat2 * mat1;

// 一次变换完成
Point3d newPt = pt.TransformBy(finalMat);

长度、面积用几何方法

【长度】

line.Length

curve.Length

【面积】

poly.Area

region.Area

【距离】

point.DistanceTo(point)

cure.GetDistanceTo(point)

【交点】

curve.IntersectWith(curve)

Curve2d.Intersect

六、选择集

定义

选择集 = 用户在 CAD 里框选/点选的一堆图元(线、圆、块、点...)

我们的代码要做4件事:

1、用PromptSelectionOptions设置选择提示

2、用SelectionFilter设置过滤条件

3、用ed.GetSelection()让用户选择

4、遍历 SelectionSet

5、拿到每一个图元的ObjectId

6、用事务打开并操作

模板

【核心固定写法】
cs 复制代码
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;

// 固定开头(必写)
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;

// 1. 设置选择提示
PromptSelectionOptions pso = new PromptSelectionOptions();
pso.MessageForAdding = "请选择图元:";

// 2. 设置过滤(替换这里的条件即可)
TypedValue[] filters = {
    new TypedValue(0, "LINE")  // 只选直线
};
SelectionFilter filter = new SelectionFilter(filters);

// 3. 获取选择集
PromptSelectionResult res = ed.GetSelection(pso, filter);

// ==============================================
// ✅ 关键:选择成功后 必须开启事务 才能操作图元
// ==============================================
if (res.Status == PromptStatus.OK)
{
    // 👇 这一行绝对不能少!!
    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        // 遍历选择集
        foreach (SelectedObject so in res.Value)
        {
            ObjectId id = so.ObjectId;

            // 👇 打开图元(必须在事务内)
            Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;

            if (ent != null)
            {
                ed.WriteMessage("\n选中图元:" + ent.Layer);
            }
        }

        tr.Commit(); // 提交事务
    }
}
【只选 直线Line】
cs 复制代码
TypedValue[] filters = {
    new TypedValue(0, "LINE")
};
【只选 圆Circle】
cs 复制代码
TypedValue[] filters = {
    new TypedValue(0, "CIRCLE")
};
【只选 指定图层】
cs 复制代码
TypedValue[] filters = {
    new TypedValue(8, "轴线")
};
【只选 指定颜色图元】(1红 2黄 3绿 4青 5蓝 6紫 7白)
cs 复制代码
TypedValue[] filters = {
    new TypedValue(62, 1)
};
【只选 指定块】
cs 复制代码
TypedValue[] filters = {
    new TypedValue(0, "INSERT"),
    new TypedValue(2, "门")
};
【多条件组合】
cs 复制代码
//只选:图层 = 墙线 + 类型 = 直线
TypedValue[] filters = {
    new TypedValue(0, "LINE"),
    new TypedValue(8, "墙线")
};
cs 复制代码
//选 墙线 OR 轴线 OR 门窗 三层
TypedValue[] filters = {
    new TypedValue(-4, "<or"),
    new TypedValue(8, "墙线"),
    new TypedValue(8, "轴线"),
    new TypedValue(8, "门窗"),
    new TypedValue(-4, "or>")
};
cs 复制代码
TypedValue[] filters = {
    new TypedValue(-4, "<and"),    // 同时满足
    
    // 条件1:直线 或 圆
    new TypedValue(-4, "<or"),
    new TypedValue(0, "LINE"),
    new TypedValue(0, "CIRCLE"),
    new TypedValue(-4, "or>"),

    // 条件2:不是轴线层
    new TypedValue(-4, "<not"),
    new TypedValue(8, "轴线"),
    new TypedValue(-4, "not>"),

    new TypedValue(-4, "and>"),
};

过滤代码表

数字 代表含义 示例
-4 逻辑符组码 ADN(且)、OR(或)、NOT(非)、XOR(异或)
0 图元类型 LINE,CIRCLE,ARC,TEXT,INSERT
1 文字内容 "ABC123"
2 块名 "门","窗","办公桌"
8 图层 "墙线","轴线","尺寸"
62 颜色 1 = 红,2 = 黄,3 = 绿,4 = 青,5 = 蓝,6 = 紫,7 = 白

逻辑符号表

逻辑 开头写法 结尾写法 意思
AND <and and> 同时满足(默认就是AND,不用写)
OR <or or> 满足一个就行
NOT <not not> 不是这个、排除这个
XOR <xor xor> 二选一(很少用)

七、图层、颜色、线型 规范

【核心原则】

图元的颜色、线型 尽量不要单独设置,全部交给图层去控制。图层管样式,图元管内容

【图层】

图层 = CAD的"文件夹" + "样式总管"

一层统一颜色、线型、线宽、开关/冻结/锁定

操作图层必须用的2个类:

LayerTable: 图层的总表(所有图层都在这里)

LayerTableRecord:一个图层的信息(名称、颜色、开关)

图层标准操作模板(创建 / 判断 / 获取)

cs 复制代码
// 固定写法:获取图层
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
    LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;

    // 判断图层是否存在
    if (lt.Has("我的图层"))
    {
        // 图层已存在,直接用
    }
    else
    {
        // 创建新图层
        LayerTableRecord ltr = new LayerTableRecord();
        ltr.Name = "我的图层";
        ltr.Color = Color.FromColorIndex(ColorMethod.ByAci, 3); // 绿色

        // 写入图层表
        tr.GetObject(lt, OpenMode.ForWrite);
        lt.Add(ltr);
        tr.AddNewlyCreatedDBObject(ltr, true);
    }
    tr.Commit();
}

【颜色】

**标准色:**1 = 红,2 = 黄,3 = 绿,4 = 青,5 = 蓝,6 = 紫,7 = 白

规范交给图层

cs 复制代码
line.Layer = "墙线";   // ✅ 墙线层是红色,线就自动变红

不规范单独给图元上色,全局硬改)

cs 复制代码
line.ColorIndex = 1;  // ❌ 不推荐!图元自己覆盖颜色

原因:

1、改图元颜色=脱离图层控制,后期无法统一修改

2、别人用你的CAD文件,改图层颜色却改不动你的图元

【线型(Linetype)】

线型也要从图层来,不要单独设置

cs 复制代码
line.Linetype = "MyLayer";  // ✅ 正确

八、事件

事件=监听+触发(订阅事件,CAD干完自动喊你)

Application.Idle:CAD 空闲时触发

用途:后台刷新、轻量任务

cs 复制代码
// 订阅/注销
Application.Idle += WhenIdle;
Application.Idle -= WhenIdle;

// 方法(名字随便改:WhenIdle / 空闲执行 / ABC 都行)
private void WhenIdle(object sender, EventArgs e)
{
    // 这里写你要做的事
}

注意:Idle 会疯狂触发 → 必须控制 "执行频率"

1、加事件间隔:每隔1~2秒跑一次,不是每次Idle都跑。

cs 复制代码
DateTime lastRun = DateTime.Now;

private void OnIdle(object sender, EventArgs e)
{
    if ((DateTime.Now - lastRun).TotalSeconds < 1) 
        return; // 不到1秒,直接退出,不执行

    // =========== 这里写你的代码 ===========
    DoSomething();

    lastRun = DateTime.Now; // 更新最后执行时间
}

2、只在"真空闲"时执行(判断是否有命令正在运行,有命令就不跑)

cs 复制代码
if (doc.CommandInProgress) return;

3、代码必须轻量化

❌ 大量遍历图元

❌ 频繁开启事务

❌ 弹窗、输入、界面阻塞

✅ 刷新界面

✅ 状态检查

✅ 轻量自动任务

4、用完立即-=注销,避免一直跑

Document.CommandWillStart:命令即将开始

cs 复制代码
doc.CommandWillStart += BeforeCommand;
doc.CommandWillStart -= BeforeCommand;

private void BeforeCommand(object sender, CommandEventArgs e)
{
    // e.CommandName 拿到命令名
}

使用场景举例:

1、禁止用户使用某些命令(比如禁止删除、禁止炸开)

2、命令开始前做初始化(比如画直线前切换图层)

3、监听用户要执行什么命令(做日志、统计、操作记录)

4、自动准备选择集/变量(命令开始前先预先加载数据)

Document.CommandEnded:命令已经结束

cs 复制代码
doc.CommandEnded += AfterCommand;
doc.CommandEnded -= AfterCommand;

private void AfterCommand(object sender, CommandEventArgs e)
{
}

Database.ObjectAppended:图元被【加入数据库】时触发

cs 复制代码
db.ObjectAppended += OnObjectAdded;
db.ObjectAppended -= OnObjectAdded;

private void OnObjectAdded(object sender, ObjectEventArgs e)
{
    // e.DBObject 拿到图元
}

注意:触发了 ObjectAppended ≠ 界面一定看得见

因为:ObjectAppended 只要图元加入数据库(任何块、任何空间)就触发。包括:

1、显示空间(看得见)

模型空间 ModelSpace

图纸空间 PaperSpace

2、非显示空间(看不见)

块定义内部(普通块、匿名块、内部块)

只进数据库、没放到任何空间里,例如:db.AddDBObject(line);

【正确的显示流程】

1、new Line () → 创建图元(内存)

2、添加到模型空间 ModelSpace → 自动触发 ObjectAppended

3、事务 Commit

4、界面显示

【如何判断是不是真正滑倒界面上

cs 复制代码
if (ent.BlockId == db.CurrentSpaceId)
{
    // ✅ 真正显示在模型/图纸空间
}
else
{
    // ❌ 在块里、或其他空间,界面看不见
}

Database.ObjectErased:有东西被删除

cs 复制代码
db.ObjectErased += OnObjectDeleted;
db.ObjectErased -= OnObjectDeleted;

private void OnObjectDeleted(object sender, ObjectEventArgs e)
{
}

Database.ObjectModified:图元被修改

cs 复制代码
db.ObjectModified += OnObjectChanged;
db.ObjectModified -= OnObjectChanged;

private void OnObjectChanged(object sender, ObjectEventArgs e)
{
}

Document.BeginSave / EndSave:保存开始 / 结束

cs 复制代码
// 保存前
doc.BeginSave += BeforeSave;
doc.BeginSave -= BeforeSave;

private void BeforeSave(object sender, DocumentBeginSaveEventArgs e)
{
    // e.FileName 文件名
}


//保存后
doc.EndSave += AfterSave;
doc.EndSave -= AfterSave;

private void AfterSave(object sender, EventArgs e)
{
}

SystemEvents.AppDomainUnload:插件卸载时(统一注销所有事件)

cs 复制代码
AppDomain.CurrentDomain.DomainUnload += OnPluginUnload;

private void OnPluginUnload(object sender, EventArgs e)
{
    // 这里把所有事件 -= 一遍,防崩溃
    Application.Idle -= WhenIdle;
    doc.CommandWillStart -= BeforeCommand;
    // ...其他事件都 -=
}



System.AppDomain.CurrentDomain.DomainUnload -= OnDomainUnload; // 一般不用

通用写法套路

cs 复制代码
对象.事件 += 方法;    //订阅
对象.事件 -= 方法;    //注销,不注销 = 内存泄漏 = 崩溃 **

private void 方法(object sender, 参数 e)
{
    // 这里写你要干的事!!!
}
【文档类】
  1. CommandEnded(命令结束时触发→ 自动修改刚画的图元)

  2. BeginSave / EndSave(保存前 / 保存后→ 自动检查、自动处理)

  3. DocumentActivated / DocumentDestroyed(切换文档、关闭文档)

【数据库(图元)类】
  1. ObjectAppended(图元被画出来时触发→ 自动改图层、自动编号)

  2. ObjectErased(图元被删除时)

  3. ObjectModified(图元被修改时(移动、旋转、拉伸))

【系统类】
  1. SystemEvents.AppDomainUnload(插件卸载时→ 统一注销所有事件,防止崩溃)

  2. Application.SystemQuiescent(CAD 完全启动完成后)

  3. LayerModified / LayerDeleted(图层被修改 / 删除)

  4. LinetypeModified(线型被修改)

常用事件全套完整可运行 Demo

cs 复制代码
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;

public class EventDemo
{
    // 全局保存 doc 和 db,方便事件用
    private Document doc = Application.DocumentManager.MdiActiveDocument;
    private Database db => HostApplicationServices.WorkingDatabase;

    // 一次性订阅所有事件
    [CommandMethod("StartEvents")]
    public void StartEvents()
    {
        // 1. 空闲事件
        Application.Idle += OnIdle;

        // 2. 命令开始/结束
        doc.CommandWillStart += OnCommandWillStart;
        doc.CommandEnded += OnCommandEnded;

        // 3. 图元增删改
        db.ObjectAppended += OnObjectAppended;
        db.ObjectErased += OnObjectErased;
        db.ObjectModified += OnObjectModified;

        // 4. 保存事件
        doc.BeginSave += OnBeginSave;
        doc.EndSave += OnEndSave;

        // 5. 插件卸载时统一清理(只+不-)
        AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;

        doc.Editor.WriteMessage("\n✅ 事件已启动");
    }

    // 手动停止事件(也会被卸载时自动调用)
    [CommandMethod("StopEvents")]
    public void StopEvents()
    {
        UnsubscribeAll();
        doc.Editor.WriteMessage("\n❌ 事件已停止");
    }

    // ====================== 统一注销所有事件(核心)======================
    private void UnsubscribeAll()
    {
        Application.Idle -= OnIdle;
        doc.CommandWillStart -= OnCommandWillStart;
        doc.CommandEnded -= OnCommandEnded;
        db.ObjectAppended -= OnObjectAppended;
        db.ObjectErased -= OnObjectErased;
        db.ObjectModified -= OnObjectModified;
        doc.BeginSave -= OnBeginSave;
        doc.EndSave -= OnEndSave;
    }

    // ====================== 各个事件方法 ======================

    // 空闲
    private void OnIdle(object sender, EventArgs e)
    {
        // 轻量代码,别写重逻辑
    }

    // 命令即将开始
    private void OnCommandWillStart(object sender, CommandEventArgs e)
    {
        Editor ed = doc.Editor;
        ed.WriteMessage($"\n→ 命令开始: {e.CommandName}");
    }

    // 命令结束
    private void OnCommandEnded(object sender, CommandEventArgs e)
    {
        Editor ed = doc.Editor;
        ed.WriteMessage($"\n← 命令结束: {e.CommandName}");
    }

    // 图元添加
    private void OnObjectAppended(object sender, ObjectEventArgs e)
    {
        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            if (e.DBObject is Entity ent)
            {
                // 真正显示在模型空间才打印
                if (ent.BlockId == db.CurrentSpaceId)
                {
                    doc.Editor.WriteMessage($"\n➕ 添加图元: {ent.GetType().Name}");
                }
            }
            tr.Commit();
        }
    }

    // 图元删除
    private void OnObjectErased(object sender, ObjectEventArgs e)
    {
        doc.Editor.WriteMessage($"\n➖ 删除图元: {e.DBObject.GetType().Name}");
    }

    // 图元修改
    private void OnObjectModified(object sender, ObjectEventArgs e)
    {
        // 图元被移动/旋转时触发
    }

    // 保存前
    private void OnBeginSave(object sender, DocumentBeginSaveEventArgs e)
    {
        doc.Editor.WriteMessage($"\n💾 准备保存: {e.FileName}");
    }

    // 保存后
    private void OnEndSave(object sender, EventArgs e)
    {
        doc.Editor.WriteMessage("\n✅ 保存完成");
    }

    // 插件卸载时自动清理(防止崩溃)
    private void OnDomainUnload(object sender, EventArgs e)
    {
        UnsubscribeAll();
    }
}

九、性能要点

1、少遍历全图,多用选择集/过滤

(遍历全图巨慢)

2、批量操作统一一个事务。

不要每操作一个图元就开一次事务,N个操作用一个事务(频繁事务巨卡、崩溃)

3、不要在Idle里做heavy操作

Idle会疯狂触发

Heavy = 遍历、大量事务、循环、弹窗

正确做法:加时间间隔、轻量判断

4、关闭屏幕刷新(提速神器)

cs 复制代码
ed.SetSuppressScreenDisplay(true);  // 关闭刷新
// 你的批量操作...
ed.SetSuppressScreenDisplay(false); // 恢复刷新

十、常见坑

  • 没事务 / 没 Commit
  • ForRead 想改图 → 报错
  • 持有 Entity 跨事务 → 崩溃
  • 事件没注销 → 内存泄漏
  • 多线程直接操作 CAD → 必崩
  • GetLastRect 遍历全图 → 大图卡爆
  • 没 try/catch → 闪退、丢图、崩 CAD
  • 批量操作不关刷新 → 巨慢
  • Idle 做 heavy 操作 → 卡到爆
  • 选择集不过滤 → 遍历全图慢死
  • 忘记 Dispose / 释放资源 → 内存越来越大
相关推荐
CheerWWW2 小时前
C++学习笔记——this关键字、对象生命周期(栈作用域)、智能指针、复制与拷贝构造函数
c++·笔记·学习
温天仁2 小时前
西门子PLC编程实践教程:工控工程案例学习
开发语言·学习·自动化·php
charlie1145141913 小时前
嵌入式C++教程实战之Linux下的单片机编程:从零搭建 STM32 开发工具链(5):调试进阶篇 —— 从 printf 到完整 GDB 调试环境
linux·c++·单片机·学习·嵌入式·c
Moqiqiuzi3 小时前
ET8.1-ECS组件式编程
笔记·学习
VelinX3 小时前
【个人学习||spring】spring ai
人工智能·学习·spring
chools4 小时前
Java后端拥抱AI开发之个人学习路线 - - Spring AI【第三期】(向量数据库 + RAG检索增强生成)
java·人工智能·学习·spring·ai
AI360labs_atyun4 小时前
我在命令行里养了只电子宠物,还顺便学会了Claude Code
人工智能·科技·学习·ai·宠物
记录无知岁月4 小时前
【学习笔记】学术英语单词总结
学习·accumulation·english word
xiaoxiaoxiaolll4 小时前
《Light》刊发北大新成果:谐振耦合架构实现超宽带孤子微梳,能效创纪录
学习