14

我正在创建一个 Visual Studio 包(这是我的第一次),我的最终目标是为仅适用于某些文件类型的解决方案资源管理器创建一个上下文菜单项。(我认为这将是一个常见的事情,但没有找到任何像样的教程,所以如果你知道任何请告诉我)

我按照一个简单的 MSDN 指南首先在工具栏中创建了一个项目(我忘记了在哪里链接它),这很好。

然后我找到了一种将其移动到解决方案资源管理器上下文菜单的方法。这是通过操作.vsct文件并具有如下元素来实现的:

<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE"/>

这可能无关紧要,但我正在尝试设置场景。

现在,因为我只想显示某些文件类型的项目,所以我需要找到一种方法来在按下右键单击按钮时检查文件。缩短了长时间的搜索,我找到了这个并最终得到以下代码:

protected override void Initialize()
{
    //stuff
    OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
    menuItem.BeforeQueryStatus += menuItem_BeforeQueryStatus;
    //more stuff
}

void menuItem_BeforeQueryStatus(object sender, EventArgs e)
{
    var myCommand = sender as OleMenuCommand;
    myCommand.Text = "NEW NAME";
}

在上面的示例中,我只是尝试设置文本以尝试证明它有效,我知道有一个Visible属性,但我希望这一步首先起作用。该BeforeQueryStatus事件被触发,调试显示代码按预期执行。但是,上下文菜单项没有变化,它与原始文本保持一致。

我在这里想念什么?为什么不更新?

4

2 回答 2

24

好的,所以我终于找到了解决此问题的方法,您需要做几件事...

第 1 步

我们需要指定 VSPackage 应该“自动加载”,我们这样做是为了在显示 ContextMenu 时执行代码,因为通常 VSPackage 在 UI 显示之前不会初始化(即菜单项已被单击)。为此,我们向 Package 类添加一个属性,如下所示:

[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
public sealed class MyFirstPackage : Package

您可能想知道那个 GUID 值是什么,在这种情况下它代表UICONTEXT_SolutionExists常量,这意味着当存在解决方案时包将自动加载(所以当我们创建一个新的或加载一个时)。我从这里得到了这些信息,你可能会知道有许多不同的 VSConstants可以使用。

这里还有一些资源列出了可以使用的其他 GUID 值:

第 2 步

现在BeforeQueryStatus代码在正确的位置执行,为什么代码实际上没有改变任何东西仍然令人困惑(在我的问题中,我试图改变Text. 好吧,答案是,因为我们需要授予包这样做的权限(至少我认为它是这样的)。

为此,我们必须编辑.vsct文件。在里面我们可以找到一个Buttons元素,里面应该是我们的 ContextMenu Button。默认情况下,有一些评论提到了CommandFlag节点的使用——这就是我们想要的。

为了允许我们的包更改,Text我们必须添加以下节点:

<CommandFlag>TextChanges</CommandFlag>

现在,如果我们运行 VSPackage,它应该会按预期工作!

如果您希望允许更改Visibility菜单项的权限(这是我最初的目标),那么您可以使用以下内容CommandFlag

<CommandFlag>DynamicVisibility</CommandFlag>

这里有一个完整的命令标志列表,并描述了它们的作用。

于 2013-03-22T10:21:18.703 回答
9

您可以使用以下命令,而不是直接使用 musefan 的答案中提到的 guid:

    [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids.SolutionExists)]

请参阅:UIContextGuids 类以了解所有 guid 常量。

于 2014-10-22T13:17:37.213 回答