确定选择了哪个Visual Studio上下文菜单?

时间:2013-05-14 10:01:37

标签: visual-studio-2012 add-in

我正在编写VS2012加载项,向Build Explorer上下文菜单添加命令(请参阅related question)。该命令将添加到2个不同的上下文菜单中:

  1. 构建资源管理器
  2. 团队资源管理器,构建页面,我的构建部分
  3. 当我调用一个回调时,我怎么知道它是哪一个?

    我尝试了重点控制(使用P / Invoke为this question建议)。但是,它得到(1)的Tabs容器,(2)为null。我可以尝试将控件转换为选项卡式容器,但这听起来很糟糕......

    有更好的选择吗?

2 个答案:

答案 0 :(得分:0)

通过评论重新设定,并建立了链接:

由于菜单项显示在每个地方,似乎没有办法在加载项之间区分它们,您应该添加两个命令并根据它们的上下文区分它们。

不是将加载项转换为VS-Package MZ-Tools HOWTO: Controlling the state of command in a Visual Studio add-in,而是尝试MZ-Tools HOWTO: Use the IVsMonitorSelection ...,您也可以从加载项中获取它。

但是:

  

AddNamedCommand和QueryStatus方法都不尊重   隐形状态:必须隐形的按钮......   仍然是残疾而非隐形。

我认为这使得无法以合适的方式从加载项执行此操作,但也许您可以检查上下文。

如果您尝试将命令/菜单迁移到VSPackage并为菜单项创建自定义UIContext或找到合适的预定义项,则可以采取其他方式。我无法访问使用Build Explorer增强的Studio,因此我无法尝试。

以下讨论是关于vs-packages的自定义上下文: http://davedewinter.com/2008/04/05/dynamic-menu-commands-in-visual-studio-packages-part-3/
遗憾的是链接从帖子中断开,我无法访问第1部分和第2部分。这是关于从一开始就讨论问题的。 但无法保证您可以创建适合您的上下文。

只有我在团队资源管理器中找到的上下文ID是guidTeamProjectCmdUIContext。 它位于Visual Studio 2010 SDK中的vsshilds.h,vsshell * .h也包含其他几个。

MSDN: Vsct files定义命令,菜单等。来自包裹。

项目的

Condition属性:
http://msdn.microsoft.com/en-us/library/bb491718.aspx
http://msdn.microsoft.com/en-us/library/bb166515.aspx

命令和工具栏的

MSDN: VisibilityItem元素。

  

VisibilityItem元素确定命令和工具栏的静态可见性。   ...加载VSPackage后,Visual Studio期望命令可见性由VSPackage而不是VisibilityItem确定。

最后关于预定义的Context Guids:
http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.uicontextguids80.aspx
http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.uicontextguids.aspx

答案 1 :(得分:0)

我的新/其他想法 - 它与你的相似:

您应该尝试监控最后激活的窗口。

如果为命令创建事件处理程序,则可以在命令触发时检查哪个窗口处于活动状态。命令的简单evenent处理程序:

void cmdEvents_BeforeExecute( string guid, int ID, object customIn, object customOut, ref bool cancelDefault )
{
  Window2 teamExplorer = _applicationObject.Windows.Item("Team Explorer") as Window2;
  if (_applicationObject.ActiveWindow.Caption == teamExplorer.Caption)
  {
       //You are called from Team Explorer
  }
  else
  {
       //Somewhere else
  }
}

您可以订阅的方式:

static _dispCommandEvents_BeforeExecuteEventHandler _myHandler;
static CommandEvents _cmdEvents;

public void OnConnection(...)
{
   Command command = ...; // Init your command 
   int ID = command.ID;
   string GUID = command.Guid;

   CommandEvents _cmdEvents = _applicationObject.Events.get_CommandEvents(GUID, ID);

   _myHandler = new _dispCommandEvents_BeforeExecuteEventHandler(cmdEvents_BeforeExecute);

   _cmdEvents.BeforeExecute += _myHandler;
}

您可以找到一种更好的方法来通过GUID识别窗口。你应该至少保持_cmdEvents为静态,因为当它被去除污染时,你的事件处理程序可能会消失(至少对内部命令而言)。

在OnDisconnection中,您应该取消订阅。