VSX是VS扩展,可以针对不同项目编写插件,虽然接触VSX的时间并不多,但是当了解VSX后深刻感受到VSX的魅力。
VSX的材料比较少,配置文件也很繁琐,当初我也走了不少弯路。
这篇文章将帮助您更好的管理Package文件(继承Package、注册命令的那个文件),想要理解这篇文章您应当对VSX有基础的了解,确保自己可以建立一个基础的VSX菜单,如果目前您还不了解VSX也没关系,我推荐您先阅读明年我18的文章。
看过基础材料后,感觉Package文件的内容真是多,包括初始化、注册控件、菜单过滤、回调,就算把菜单过滤和回调挪走,一个典型的注册命令代码也有这么多:
1 OleMenuCommand cmdidFindInSolutionExplorer = new OleMenuCommand(FindInSolutionExplorerCallback, 2 new CommandID(GuidList.guidConvenientCmdSet, (int)PkgCmdIDList.cmdidFindInSolutionExplorer)); 3 cmdidFindInSolutionExplorer.BeforeQueryStatus += new EventHandler(MenuFilter.ClinicalFilter); 4 mcs.AddCommand(cmdidFindInSolutionExplorer);
随着插件功能的丰富,百十来个命令让Package文件拥挤不堪,再加上过滤和回调,每次打开这个文件都头皮发麻,(就算把回调和过滤分离成单独文件,大批的回调和过滤函数也。。。)。
下面的解决方案可以让你优雅的注册命令,是读codemaid源码时学到的:
首先定义一个抽象类BaseCommand继承OleMenuCommand,并在BaseCommand下定义两个事件OnBeforeQueryStatus与OnExecute分别对应过滤和回调:
1 private static void BaseCommand_BeforeQueryStatus(object sender, EventArgs e) 2 { 3 BaseCommand command = sender as BaseCommand; 4 if (command != null) 5 { 6 command.OnBeforeQueryStatus(); 7 } 8 } 9 protected virtual void OnBeforeQueryStatus() 10 { 11 Enabled = true; 12 } 13 private static void BaseCommand_Execute(object sender, EventArgs e) 14 { 15 BaseCommand command = sender as BaseCommand; 16 if (command != null) 17 { 18 command.OnExecute(); 19 } 20 } 21 protected virtual void OnExecute() 22 { 23 }
在构造函数中注册事件:
1 protected ClinicalVSXPackage Pkg { get; private set; } 2 3 protected BaseCommand(ClinicalVSXPackage pkg, CommandID id) 4 : base(BaseCommand_Execute, id) 5 { 6 Pkg = pkg; 7 BeforeQueryStatus += BaseCommand_BeforeQueryStatus; 8 }
Pkg是将Package类本身传进来,方便传递dte等成员。
这样就可以在Package文件中优雅的注册命令了:
1 private readonly ICollection<BaseCommand> _commands = new List<BaseCommand>(); 2 3 private void RegisterCommands() 4 { 5 var mcs = MenuCommandService; 6 if (null == mcs) 7 return; 8 _commands.Add(new 命令1(this)); 9 _commands.Add(new 命令2(this)); 10 _commands.Add(new 命令3this)); 11 .... 12 foreach (var command in _commands) 13 mcs.AddCommand(command); 14 }
这样当你打算新建一个命令,需要添加一个独立的类继承刚才的BaseCommand
并实现过滤和回调事件,一个典型的命令类:
1 internal class 命令1 : BaseCommand 2 { 3 public 命令1(Package pkg) 4 : base(pkg, new CommandID(CmdSetID, (int)PkgCmdIDList.命令ID)) 5 { } 6 7 protected override void OnBeforeQueryStatus() 8 { 9 } 10 protected override void OnExecute() 11 { 12 base.OnExecute(); 13 } 14 }
时间: 2024-10-09 10:53:33