[免费]CAD二次开发插件源码分享:一键将普通文字转为属性定义,做块神器!
做过图框或者属性块的朋友都知道,“定义属性” (ATTDEF) 是个体力活。
😫 传统做法: 对着已经画好的文字,重新输入命令、设置标签、对齐点、字高、图层… 如果有100个文字要转,手都要断。
🚀 极客做法: 框选所有文字 -> 执行命令 -> 瞬间全部变成属性定义,且位置、样式完全保留!
今天分享一段 C# 硬核源码,完美实现 DBText 到 AttributeDefinition 的无损转换,特别处理了最让人头疼的“对齐方式”问题。
看似简单的“转换”,其实涉及到 CAD 数据库底层几十个属性的搬运。如果只是简单的复制坐标,你会发现转换后的文字位置会乱跑(特别是中对齐、右对齐的文字)。
我们的代码逻辑如下:
- 筛选:使用过滤器只抓取单行文字 (DBText)。
- 几何克隆:复制插入点、高度、旋转角、宽度比例、倾斜角。
- 样式克隆:复制图层、颜色、线型、字型 (TextStyle)。
- 对齐同步:这一点最关键!必须同时同步
HorizontalMode、VerticalMode和AlignmentPoint。 - 标签清洗: 属性标签 (Tag) 不允许有空格,代码自动将空格替换为下划线。

新建类 TextUtils,引用 CAD 核心库,编译后使用命令 TextToAtt 即可。
using System;using Autodesk.AutoCAD.Runtime;using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.DatabaseServices;using Autodesk.AutoCAD.EditorInput;using Autodesk.AutoCAD.Geometry;using Application = Autodesk.AutoCAD.ApplicationServices.Application;namespace CADDevTools{ public static class TextUtils { [CommandMethod("TextToAtt")] public static void ConvertTextToAttribute() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; // 1. 设置过滤器,只允许选择单行文字 (DBText) TypedValue[] filterList = new TypedValue[] { new TypedValue((int)DxfCode.Start, "TEXT") }; SelectionFilter filter = new SelectionFilter(filterList); // 2. 提示用户选择 PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "\n请选择要转换为属性定义的单行文字: "; PromptSelectionResult psr = ed.GetSelection(pso, filter); if (psr.Status != PromptStatus.OK) return; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); foreach (SelectedObject so in psr.Value) { // 获取选中的文字对象 DBText textEnt = tr.GetObject(so.ObjectId, OpenMode.ForWrite) as DBText; if (textEnt == null) continue; // 3. 创建新的属性定义 AttributeDefinition attDef = new AttributeDefinition(); // 初始化默认属性 attDef.SetDatabaseDefaults(); // --- 核心步骤:复制所有通用属性 --- // A. 基础几何与显示属性 attDef.Position = textEnt.Position; attDef.Height = textEnt.Height; attDef.Rotation = textEnt.Rotation; attDef.WidthFactor = textEnt.WidthFactor; // 宽度比例 attDef.Oblique = textEnt.Oblique; // 倾斜角度 attDef.TextStyleId = textEnt.TextStyleId; // 字体样式 attDef.Normal = textEnt.Normal; // 法向量 attDef.Thickness = textEnt.Thickness; // 厚度 // B. 图层、颜色、线型 attDef.LayerId = textEnt.LayerId; attDef.Color = textEnt.Color; attDef.LinetypeId = textEnt.LinetypeId; attDef.LineWeight = textEnt.LineWeight; attDef.LinetypeScale = textEnt.LinetypeScale; attDef.Visible = textEnt.Visible; // C. 关键:处理对齐方式 (Alignment) // 注意:必须先设置 Mode,再设置 AlignmentPoint attDef.HorizontalMode = textEnt.HorizontalMode; attDef.VerticalMode = textEnt.VerticalMode; // 如果文字不是默认的左下角对齐,需要同步对齐点 if (textEnt.HorizontalMode != TextHorizontalMode.TextLeft || textEnt.VerticalMode != TextVerticalMode.TextBase) { attDef.AlignmentPoint = textEnt.AlignmentPoint; // 强制调整对齐以确保显示正确 attDef.AdjustAlignment(db); } // D. 属性特有设置 (Tag, Prompt, Value) // Tag 不能包含空格,这里简单替换空格为下划线 string originalContent = textEnt.TextString; string validTag = originalContent.Replace(" ", "_").ToUpper(); // 如果 Tag 为空,给定一个默认值防止报错 if (string.IsNullOrWhiteSpace(validTag)) validTag = "TAG_" + DateTime.Now.Ticks.ToString(); attDef.Tag = validTag; // 标签 (程序识别用) attDef.Prompt = originalContent; // 提示 (插入块时显示) attDef.TextString = originalContent; // 默认值 // E. 其他属性设置 attDef.Verifiable = true; // 验证 attDef.LockPositionInBlock = true; // 在块中锁定位置 attDef.Constant = false; // 非固定属性 attDef.Invisible = false; // 可见 // 4. 将新属性添加到数据库 btr.AppendEntity(attDef); tr.AddNewlyCreatedDBObject(attDef, true); // 5. 删除原有文字 textEnt.Erase(); } tr.Commit(); } ed.WriteMessage($"\n✅ 成功转换 {psr.Value.Count} 个文字对象为属性定义。"); } }}
🔥 对齐点的地狱 (Alignment Hell)
这是新手最容易翻车的地方。DBText 和 AttributeDefinition 都有 Position 和 AlignmentPoint。如果文字是“左对齐”,CAD只认 Position;如果文字是“中对齐”或“右对齐”,CAD优先认 AlignmentPoint。代码中的 AdjustAlignment(db) 非常重要,它能确保属性定义在创建后,几何位置与对齐模式能够正确匹配,否则字会“飞”走。
🔥 标签 (Tag) 的限制
CAD 的属性标签 (Tag) 是不允许包含空格的。如果你的原文字是 “Project Name”,直接赋值给 Tag 会导致创建失败。代码中使用了 Replace(" ", "_") 将其自动转换为 “PROJECT_NAME”,这是一个非常实用的容错细节。
📌 总结
通过这个插件,你可以先用普通文字工具(所见即所得)把图框里的内容排版好,然后一键刷成属性。这比直接用 ATTDEF 对话框一个一个调参数要快10倍以上!
夜雨聆风
