C# CAD二次开发中CommandMethodAttribute 详解
·
CommandMethodAttribute 详解
这是 AutoCAD .NET API 中最重要的特性之一,用于将 C# 方法注册为 AutoCAD 命令。我来详细解释每个重载及其应用场景。
一、所有重载及参数说明
// 我画了一张表,帮你快速定位参数含义
| 参数 | 类型 | 必需 | 说明 | 示例 |
|---|---|---|---|---|
globalName |
string | ✅ | 命令的全局名称(CAD命令行中输入的名称) | "DrawWall" |
groupName |
string | ❌ | 命令组名(用于命令分组管理) | "MyWallTools" |
localizedNameId |
string | ❌ | 本地化名称ID(多语言支持) | "IDS_CMD_DRAWWALL" |
flags |
CommandFlags | ❌ | 命令行为标志(默认Modal) | CommandFlags.Modal |
contextMenuExtensionType |
Type | ❌ | 右键菜单扩展类型 | typeof(MyContextMenu) |
helpFileName |
string | ❌ | 帮助文件名 | "MyAppHelp.chm" |
helpTopic |
string | ❌ | 帮助主题ID | "WallTools" |
二、7个重载详解(按复杂度递增)
重载1:最简单的命令注册
public CommandMethodAttribute(string globalName)
意义: 最基础的命令注册,适合快速开发、测试阶段。
示例:
// 最简单的命令,在CAD中输入 "Hello" 即可执行
[CommandMethod("Hello")]
public void SayHello()
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nHello AutoCAD!");
}
// CAD命令行使用:
// 命令: Hello
// 输出: Hello AutoCAD!
使用场景:
- 快速原型开发
- 内部工具
- 单一功能的简单命令
重载2:带命令标志
public CommandMethodAttribute(string globalName, CommandFlags flags)
意义: 控制命令的执行模式和行为。
示例:
// 只读命令,不会锁定文档
[CommandMethod("CheckDrawing", CommandFlags.Session)]
public void CheckDrawing()
{
// 可以在不锁定文档的情况下检查图纸信息
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor editor = doc.Editor;
editor.WriteMessage($"\n{DateTime.Now}: 图纸检查完成");
}
// 透明命令(可以在其他命令执行期间调用)
[CommandMethod("ShowAngle", CommandFlags.Transparent)]
public void ShowAngle()
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n当前角度: 0°");
}
CommandFlags 枚举详解:
| 标志 | 值 | 说明 | 典型场景 |
|---|---|---|---|
Modal |
0 | 模态命令(默认) | 大部分绘图命令 |
Transparent |
1 | 透明命令 | 辅助查询命令(如’ZOOM) |
NoPerspective |
2 | 禁止透视模式 | 3D特殊控制 |
Session |
4 | 会话级命令 | 多文档操作 |
NoHistory |
8 | 不记录命令历史 | 临时操作 |
NoUndoMarker |
16 | 不创建撤销标记 | 批量操作优化 |
使用场景:
- 需要在其他命令中执行的工具(Transparent)
- 跨文档操作(Session)
- 性能优化(NoHistory)
重载3:命令分组
public CommandMethodAttribute(string groupName, string globalName, CommandFlags flags)
意义: 将相关命令组织在一起,便于管理和查找。
示例:
public class WallCommands
{
// 所有墙线相关命令都在 "WallTools" 组下
[CommandMethod("WallTools", "DrawWall", CommandFlags.Modal)]
public void DrawWall()
{
// 绘制墙线
}
[CommandMethod("WallTools", "EditWall", CommandFlags.Modal)]
public void EditWall()
{
// 编辑墙线
}
[CommandMethod("WallTools", "DeleteWall", CommandFlags.Modal)]
public void DeleteWall()
{
// 删除墙线
}
}
// 在CAD中可以使用 ARX 命令查看分组
// 命令: ARX -> 命令组 -> WallTools
使用场景:
- 大型插件系统
- 功能模块化管理
- 团队协作开发
重载4:支持本地化
public CommandMethodAttribute(string groupName, string globalName, string localizedNameId, CommandFlags flags)
意义: 支持多语言版本,通过资源文件提供本地化的命令名和提示。
示例:
// 定义本地化ID,支持中英文切换
[CommandMethod("WallTools", "DrawWall", "IDS_CMD_DRAWWALL_CN", CommandFlags.Modal)]
public void DrawWall()
{
// 中文环境下显示: 绘制墙线
// 英文环境下显示: Draw Wall
}
// 资源文件 (Resources.resx)
// IDS_CMD_DRAWWALL_CN = "绘制墙线"
// IDS_CMD_DRAWWALL_EN = "DrawWall"
使用场景:
- 国际化应用程序
- 面向不同语言用户的产品
- 需要动态切换语言的CAD插件
重载5:右键菜单扩展
public CommandMethodAttribute(string groupName, string globalName, string localizedNameId, CommandFlags flags, Type contextMenuExtensionType)
意义: 将命令添加到CAD的右键快捷菜单中。
示例:
// 定义右键菜单扩展
public class WallContextMenu : ContextMenuExtension
{
public WallContextMenu()
{
Title = "墙线工具";
MenuItem item1 = new MenuItem("绘制墙线");
item1.Click += (s, e) => {
Application.DocumentManager.MdiActiveDocument.SendStringToExecute("DrawWall ", true, false, true);
};
MenuItems.Add(item1);
}
}
// 使用右键菜单扩展
[CommandMethod("WallTools", "DrawWall", "IDS_CMD_DRAWWALL", CommandFlags.Modal, typeof(WallContextMenu))]
public void DrawWall()
{
// 绘制墙线
// 右键菜单中也会出现此命令
}
使用场景:
- 提升用户体验
- 快速访问常用命令
- 专业工具软件
重载6:帮助主题
public CommandMethodAttribute(string groupName, string globalName, string localizedNameId, CommandFlags flags, string helpTopic)
意义: 为命令关联帮助文档,用户按F1时自动打开。
示例:
// 关联HTML帮助主题
[CommandMethod("WallTools", "DrawWall", "IDS_CMD_DRAWWALL", CommandFlags.Modal, "WallTools/DrawWall")]
public void DrawWall()
{
try
{
// 绘制墙线逻辑
}
catch (Exception ex)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\n错误: {ex.Message}");
// 按F1查看帮助
}
}
// 在帮助文件中的锚点
// MyAppHelp.htm#WallTools/DrawWall
使用场景:
- 商业软件产品
- 复杂功能需要文档支持
- 企业内部工具
重载7:完整参数(全部功能)
public CommandMethodAttribute(string groupName, string globalName, string localizedNameId, CommandFlags flags, Type contextMenuExtensionType, string helpFileName, string helpTopic)
意义: 功能最全的重载,包含所有扩展功能。
示例:
// 最完整的命令注册
[CommandMethod(
"WallTools", // 命令组
"DrawWall", // 命令名
"IDS_CMD_DRAWWALL_CN", // 本地化ID
CommandFlags.Modal, // 执行模式
typeof(WallContextMenu), // 右键菜单
"ArchitectCAD.chm", // 帮助文件
"WallTools/DrawWall" // 帮助主题
)]
public void DrawWall()
{
// 最完整的命令实现
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor editor = doc.Editor;
editor.WriteMessage("\n开始绘制墙线...");
// 实现逻辑...
}
三、开发中的实际意义
1. 组织管理
// 按模块分组
[CommandMethod("Architecture", "DrawWall", ...)] // 建筑模块
[CommandMethod("Architecture", "EditWall", ...)]
[CommandMethod("MEP", "DrawPipe", ...)] // 机电模块
[CommandMethod("MEP", "DrawDuct", ...)]
[CommandMethod("Structure", "DrawBeam", ...)] // 结构模块
2. 权限控制
// 只读命令,不需要锁定文档
[CommandMethod("Viewer", "QuickView", CommandFlags.Session)]
public void QuickView() { ... }
// 可撤销的命令
[CommandMethod("Editor", "ModifyObject", CommandFlags.Modal)]
public void ModifyObject() { ... }
3. 用户体验优化
// 常用工具加入右键菜单
[CommandMethod("Tools", "QuickCopy", ..., typeof(QuickCopyMenu))]
public void QuickCopy() { ... }
// 带帮助文档
[CommandMethod("Tools", "AdvancedFilter", ..., "Tools/Filter")]
public void AdvancedFilter() { ... }
四、最佳实践
1. 命名规范
// 使用动词+名词命名
[CommandMethod("DrawRect", "DR")] // 绘制矩形
[CommandMethod("CreateBlock", "CB")] // 创建块
[CommandMethod("ExportPDF", "EP")] // 导出PDF
// 避免模糊名称
// ❌ [CommandMethod("DoIt")]
// ✅ [CommandMethod("CalculateArea")]
2. 错误处理
[CommandMethod("SafeCommand")]
public void SafeCommand()
{
try
{
// 业务逻辑
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
// AutoCAD异常
Application.ShowAlertDialog($"AutoCAD错误: {ex.Message}");
}
catch (System.Exception ex)
{
// 其他异常
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\n系统错误: {ex.Message}");
}
}
3. 版本兼容
#if ACAD2014
[CommandMethod("DrawWall2014", CommandFlags.Modal)]
#elif ACAD2016
[CommandMethod("DrawWall2016", CommandFlags.Modal)]
#endif
public void DrawWall()
{
// 不同版本的实现
}
我来给每个参数配上直观的Demo代码,让你一目了然。
完整Demo:一个"建筑墙线"命令的各种玩法
using System;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
namespace WallCommandDemo
{
// ============================================
// 1. globalName - 命令名
// 作用:你在CAD命令行敲什么,命令就执行什么
// ============================================
/// <summary>
/// 最简单的注册,只有一个globalName
/// 在CAD命令行输入 "HelloCAD" 回车即可执行
/// </summary>
[CommandMethod("HelloCAD")]
public void SayHello()
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n✅ 你好!我执行了!因为我的globalName是HelloCAD");
}
// ============================================
// 2. groupName - 命令组名
// 作用:把相关命令打包,方便管理、卸载
// ============================================
/// <summary>
/// 未分组 - 散兵游勇,不好管
/// </summary>
[CommandMethod("DrawWall1")]
public void DrawWallUngrouped() { }
/// <summary>
/// 已分组 - 在ARX命令里能看到"WallTools"这个组
/// 可以整体加载/卸载这组命令
/// </summary>
[CommandMethod("WallTools", "DrawWall2", CommandFlags.Modal)]
public void DrawWallGrouped()
{
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n✅ 我在WallTools组里!用ARX命令可以看到我");
ed.WriteMessage("\n 你也可以用 LISP 卸载整个组: (command \"ARX\" \"U\" \"WallTools\")");
}
[CommandMethod("WallTools", "EditWall", CommandFlags.Modal)]
public void EditWall() { }
[CommandMethod("WallTools", "DeleteWall", CommandFlags.Modal)]
public void DeleteWall() { }
// ============================================
// 3. localizedNameId - 本地化ID
// 作用:中英文切换时,命令名自动变
// ============================================
/// <summary>
/// 你的资源文件 Resources.resx 里:
/// IDS_DRAWWALL_CN → "绘制墙线" (中文CAD显示这个)
/// IDS_DRAWWALL_EN → "DrawWall" (英文CAD显示这个)
/// </summary>
[CommandMethod("WallTools", "DrawWall", "IDS_DRAWWALL_CN", CommandFlags.Modal)]
public void LocalizedDrawWall()
{
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n✅ 这个命令支持多语言!");
ed.WriteMessage("\n 中文CAD里命令叫: 绘制墙线");
ed.WriteMessage("\n 英文CAD里命令叫: DrawWall");
}
// ============================================
// 4. flags - 命令行为标志
// 作用:控制命令怎么执行
// ============================================
/// <summary>
/// 默认 Modal 模式:执行时锁定文档,不能干别的
/// </summary>
[CommandMethod("DrawModal")]
public void ModalCommand()
{
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n🔒 我是模态命令,执行期间你不能做其他操作");
ed.WriteMessage("\n 这是默认行为,适合大部分绘图命令");
}
/// <summary>
/// Transparent 透明命令:在其他命令执行期间也能调用
/// 用法:执行DrawModal时,输入 'CheckInfo (前面加撇号)
/// </summary>
[CommandMethod("CheckInfo", CommandFlags.Transparent)]
public void TransparentCommand()
{
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n👻 我是透明命令!前面加撇号'调用我");
ed.WriteMessage("\n 比如你正在画线时输入 'CheckInfo 就能看到我");
}
/// <summary>
/// Session 会话级:不锁定文档,可以在后台监控
/// </summary>
[CommandMethod("MonitorDrawing", CommandFlags.Session)]
public void SessionCommand()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var ed = doc.Editor;
ed.WriteMessage("\n🔓 我是会话级命令,不锁定文档");
ed.WriteMessage($"\n 当前时间: {DateTime.Now}");
ed.WriteMessage($"\n 当前图纸: {doc.Name}");
}
// ============================================
// 5. contextMenuExtensionType - 右键菜单
// 作用:选中对象点右键时,出现这个命令
// ============================================
/// <summary>
/// 右键菜单类 - 必须继承 ContextMenuExtension
/// </summary>
public class WallRightClickMenu : ContextMenuExtension
{
public WallRightClickMenu()
{
Title = "🏗️ 墙线工具";
// 菜单项1
MenuItem createWallItem = new MenuItem("绘制墙线");
createWallItem.Click += (sender, e) =>
{
// 发送命令到CAD命令行
Application.DocumentManager.MdiActiveDocument
.SendStringToExecute("DrawWallFromMenu ", true, false, true);
};
MenuItems.Add(createWallItem);
// 菜单项2
MenuItem editWallItem = new MenuItem("编辑墙线");
editWallItem.Click += (sender, e) =>
{
Application.ShowAlertDialog("编辑功能待实现");
};
MenuItems.Add(editWallItem);
// 分隔线
MenuItems.Add(new MenuItem("-"));
// 菜单项3
MenuItem deleteWallItem = new MenuItem("删除墙线");
deleteWallItem.Click += (sender, e) =>
{
Application.ShowAlertDialog("删除功能待实现");
};
MenuItems.Add(deleteWallItem);
}
}
/// <summary>
/// 关联右键菜单的命令
/// 用户选中对象 → 右键 → 会出现"墙线工具"菜单
/// </summary>
[CommandMethod("DrawWallFromMenu", CommandFlags.Modal, typeof(WallRightClickMenu))]
public void DrawWallFromRightClick()
{
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n🖱️ 我是从右键菜单调用的!");
ed.WriteMessage("\n 你也可以直接输入 DrawWallFromMenu 来执行");
}
// ============================================
// 6. helpTopic - 帮助主题ID
// 作用:用户按F1时,跳转到帮助文件的指定锚点
// ============================================
/// <summary>
/// 帮助文件名 + 帮助主题
/// 用户执行命令后按F1,就会打开 MyCADHelp.chm 并定位到 WallDraw 章节
/// </summary>
[CommandMethod("AdvancedDrawWall", CommandFlags.Modal, "WallDraw")]
public void DrawWallWithHelp()
{
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n📖 如果你不会用,请按 F1 查看帮助!");
ed.WriteMessage("\n 帮助文件定位到: WallDraw 章节");
ed.WriteMessage("\n 帮助文件: MyCADHelp.chm");
// 执行命令逻辑
ed.WriteMessage("\n正在绘制高级墙线...");
}
// ============================================
// 7. helpFileName - 帮助文件名
// 作用:指定.chm帮助文件
// ============================================
/// <summary>
/// 完整版:指定帮助文件 + 帮助主题
/// F1会打开 "MyCADHelp.chm" 并跳到 "WallTools/DrawWall" 章节
/// </summary>
[CommandMethod("ProDrawWall", CommandFlags.Modal, "DrawWall", "ProWallGuide")]
public void ProfessionalDrawWall()
{
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n📖 按 F1 查看专业帮助");
ed.WriteMessage("\n 帮助文件: DrawWall.chm");
ed.WriteMessage("\n 主题: ProWallGuide");
ed.WriteMessage("\n专业墙线绘制中...");
}
// ============================================
// 🎯 综合Demo:最完整的命令注册
// ============================================
/// <summary>
/// 全部参数都用上!
/// </summary>
[CommandMethod(
"WallTools", // 组名:在ARX里能看到
"SuperDrawWall", // 命令名:用户输入这个
null, // 本地化:可空
CommandFlags.Modal, // 模态执行
typeof(WallRightClickMenu), // 右键菜单
"ArchitectWallHelp", // 帮助文件
"SuperDrawWall/Overview" // 帮助主题
)]
public void SuperDrawWall()
{
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n━━━━━━━━━━━━━━━━━━━━━━━━━━");
ed.WriteMessage("\n🌟 我是最完整的命令!");
ed.WriteMessage("\n 1. 命令组: WallTools");
ed.WriteMessage("\n 2. 命令名: SuperDrawWall");
ed.WriteMessage("\n 3. 执行模式: Modal(锁定文档)");
ed.WriteMessage("\n 4. 右键菜单: 已集成");
ed.WriteMessage("\n 5. 帮助文件: ArchitectWallHelp.chm");
ed.WriteMessage("\n 6. 帮助主题: SuperDrawWall/Overview");
ed.WriteMessage("\n━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
// ============================================
// 🧪 测试命令(检验所有功能)
// ============================================
[CommandMethod("TestAllFeatures")]
public void TestEverything()
{
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n\n╔══════════════════════════════════════╗");
ed.WriteMessage("\n║ CommandMethod 参数完整测试 ║");
ed.WriteMessage("\n╚══════════════════════════════════════╝");
ed.WriteMessage("\n\n📋 以下命令可以测试:");
ed.WriteMessage("\n HelloCAD → 测试 globalName");
ed.WriteMessage("\n DrawWall1 → 测试 无分组");
ed.WriteMessage("\n DrawWall2 → 测试 groupName");
ed.WriteMessage("\n DrawModal → 测试 Modal 标志");
ed.WriteMessage("\n 'CheckInfo → 测试 Transparent(注意前面加撇号)");
ed.WriteMessage("\n MonitorDrawing → 测试 Session");
ed.WriteMessage("\n DrawWallFromMenu → 测试 右键菜单");
ed.WriteMessage("\n AdvancedDrawWall → 测试 帮助主题(执行后按F1)");
ed.WriteMessage("\n ProDrawWall → 测试 完整帮助文件");
ed.WriteMessage("\n SuperDrawWall → 测试 全参数组合");
}
}
🎬 使用演示
在CAD里分别测试:
命令: HelloCAD
输出: ✅ 你好!我执行了!因为我的globalName是HelloCAD
命令: DrawWall2
输出: ✅ 我在WallTools组里!用ARX命令可以看到我
命令: 'CheckInfo ← 注意前面的撇号!
输出: 👻 我是透明命令!前面加撇号'调用我
命令: SuperDrawWall
输出: 🌟 我是最完整的命令!
[此时选中实体右键 → 看到"墙线工具"菜单]
[按F1 → 打开帮助文件 ArchitectWallHelp.chm]
📊 一图总结
[CommandMethod(
"WallTools", ← groupName : 把命令装进叫"WallTools"的抽屉
"SuperDrawWall", ← globalName : 用户喊"SuperDrawWall"我就动
"IDS_DRAW", ← localizedNameId : 老外喊"DrawWall"也行
CommandFlags.Modal, ← flags : 我干活时别人别打扰(锁定文档)
typeof(WallMenu), ← contextMenu : 右键菜单里有我
"Help.chm", ← helpFileName : 不懂?看Help.chm
"Topic123" ← helpTopic : 直接翻到Topic123这一页
)]
五、推荐文章
以下是一些关于 AutoCAD .NET 二次开发中 CommandMethod 的优质博文资源:
-
AutoCAD .NET API 官方文档
- CommandMethodAttribute Class
- 最权威的参考文档
-
Kean Walmsley’s Through the Interface
- Creating commands in AutoCAD using .NET
- AutoCAD 开发团队成员的博客
-
中文资源推荐
- CSDN 搜索"AutoCAD .NET CommandMethod"
- 博客园搜索"AutoCAD 二次开发 命令注册"
- 知乎搜索"AutoCAD .NET 开发"
-
书籍推荐
- 《AutoCAD VBA & VB.NET开发基础与实例教程》
- 《AutoCAD .NET 二次开发指南》
更多推荐

所有评论(0)