【问题标题】:Determining which Visual Studio context menu was selected?确定选择了哪个 Visual Studio 上下文菜单?
【发布时间】:2013-05-14 10:01:36
【问题描述】:

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

  1. 构建资源管理器
  2. 团队资源管理器,构建页面,我的构建部分

当我的一个回调被调用时,我怎么知道它是哪一个?

我尝试获得集中控制(使用 P/Invoke 作为this question 建议)。但是,它为 (1) 提供了一个 Tabs 容器,为 (2) 提供了 null。我可以尝试将控件强制转换为选项卡式容器,但这听起来很糟糕......

还有更好的选择吗?

【问题讨论】:

    标签: visual-studio-2012 add-in


    【解决方案1】:

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

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

    如果您为您的命令创建事件处理程序,那么您可能能够检查当您的命令触发时哪个窗口处于活动状态。命令的简单事件处理程序:

    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 中,您应该取消订阅。

    【讨论】:

      【解决方案2】:

      由评论重做,并建立链接:

      由于菜单项显示在每个地方,似乎无法将它们与加载项区分开来,您应该添加两个命令并根据它们的上下文区分它们。

      除了将 Add-In 转换为 VS-Package MZ-Tools HOWTO: Controlling the state of command in a Visual Studio add-in 的方法,尝试 MZ-Tools HOWTO: Use the IVsMonitorSelection ... 您也可以从 Add-In 中获取它。

      但是:

      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 确定。

      最后是关于预定义的上下文指南:
      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

      【讨论】:

      • 这不适用于这里:当我添加我的命令时,它会自动出现在两个地方,而 AFAIK 无法告诉命令只出现在一个地方。这有点道理——VS 在这两个地方显示完全相同的项目,因此与项目相关的命令应该出现在这两个地方。
      • 如果您为像解决方案这样的上下文菜单添加菜单项,则不确定您是否希望在所有情况下都使用它。例如 Tfs 命令在简单的解决方案中是不可见的。但是,如果您想区分 UI 的状态或您自己的程序,这似乎是正确的方法。您应该尝试使用一个简单的包,并获取可用的UI GIUIDs。
      猜你喜欢
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 2015-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多