问题现象
插件命令按钮在从零件/装配体切换到工程图,再切回零件/装配体后,按钮变成灰色不可用。
根本原因(四个叠加因素)
| 序号 | 原因 | 说明 |
|---|---|---|
| 1 | 命令组激活状态丢失 | Tab 只在零件/装配体中创建,切到工程图时 Tab 消失,CommandManager 上下文被重置,切回时命令组未重新激活 |
| 2 | Enable 回调缺失 | AddCommandItem2 传入了 "EnableCommand1" 等方法名,但 未实现这些方法,SolidWorks 查询不到启用状态,默认置灰。 |
| 3 | 注册表旧定义冲突 | 修改按钮定义后 UserID 未变,SolidWorks 从注册表加载旧命令组定义,新 Enable 回调未生效 |
| 4 | 事件订阅类型错误 | ISldWorks 接口不包含 ActiveDocChangeNotify,必须用 SldWorks 类或 DSldWorksEvents_Event 接口订阅 |
解决方案
用 SldWorks 类订阅事件,在文档切换后重新激活命令组
字段声明:
private SldWorks _swEventPtr; // 事件指针,SldWorks 类才能订阅 ActiveDocChangeNotify 等事件
private ICommandManager _cmdMgr; // 保存 CommandManager 引用,事件回调中需要用到
在 ConnectToSW 末尾订阅事件:
_swEventPtr = ThisSW as SldWorks;
_swEventPtr.ActiveDocChangeNotify += new DSldWorksEvents_ActiveDocChangeNotifyEventHandler(OnDocChange);
_swEventPtr.ActiveModelDocChangeNotify += new DSldWorksEvents_ActiveModelDocChangeNotifyEventHandler(OnModelChange);
事件回调中重新激活命令组:
public int OnDocChange()
{
try
{
if (_cmdMgr == null) return 0;
ICommandGroup cmdGroup = _cmdMgr.GetCommandGroup(GroupId);
if (cmdGroup != null) { cmdGroup.Activate(); }
}
return 0;
}
最后还需要在 DisconnectFromSW 中取消订阅。
if (_swEventPtr != null)
{
try
{
_swEventPtr.ActiveDocChangeNotify -= new DSldWorksEvents_ActiveDocChangeNotifyEventHandler(OnDocChange);
_swEventPtr.ActiveModelDocChangeNotify -= new DSldWorksEvents_ActiveModelDocChangeNotifyEventHandler(OnModelChange);
}
_swEventPtr = null;
}
实现 Enable 回调
在 CommandCallbacks 类中添加:
public int EnableCommand1() { return 1; }
public int EnableCommand2() { return 1; }
public int EnableCommand3() { return 1; }
返回 1 表示启用,返回 0 表示禁用(灰色)。这三个方法必须与 AddCommandItem2 中传入的 Enable 方法名完全一致。
应该是EnableCommand没有返回1的原因导致。