VSX规划Package文件

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     }

 

posted @ 2015-07-22 10:16  pappercut  阅读(284)  评论(0编辑  收藏  举报