我正在创建一个Visual Studio包(这是我的第一次),我的最终目标是为解决方案资源管理器创建一个仅适用于某些文件类型的上下文菜单项。 (我认为这将是一个常见的事情,但没有找到任何体面的教程,所以如果你知道任何请告诉我)
我遵循一个简单的MSDN指南,首先在工具栏中创建一个项目(我忘记链接它的位置),这很好。
然后我找到了将其移动到Solution Explorer上下文菜单的方法。这是通过操纵.vsct
文件并具有如下元素来实现的:
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE"/>
这可能无所谓,但我正试图设置场景。
现在,因为我只想显示某些文件类型的项目,所以我需要找到一种方法来在按下右键单击按钮时检查文件。缩短搜索时间,我found this并最终得到以下代码:
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
事件,并且调试显示代码按预期执行。但是,上下文菜单项没有变化,它保留原始文本。
我在这里缺少什么?为什么不更新?
答案 0 :(得分:23)
好的,所以我终于找到了解决这个问题的方法,你需要做几件事......
第1步:
我们需要指定VSPackage应该“自动加载”,我们这样做是为了在显示ContextMenu时执行代码,因为通常VSPackage在UI显示之前不会初始化(即菜单项已被点击)。为此,我们向Package类添加一个属性,如下所示:
[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
public sealed class MyFirstPackage : Package
您可能想知道GUID值是什么,在这种情况下它代表UICONTEXT_SolutionExists
常量,这意味着当解决方案存在时,包将自动加载(所以当我们创建一个新的或加载一个时)。 I got this information from here,您可能会知道可以使用number of different VSConstants。
以下是一些资源,列出了可以使用的其他GUID值:
第2步:
现在BeforeQueryStatus
代码正在正确的位置执行,但为什么代码实际上没有改变任何东西仍然令人困惑(在我的问题中,我尝试更改Text
)。嗯,答案是,因为我们需要授予包的许可(至少这是我认为的方式)。
为此,我们必须编辑.vsct
文件。在那里我们可以找到Buttons
元素,其中应该是我们的ContextMenu Button
。默认情况下,有一些注释提到了CommandFlag
节点的使用 - 这就是我们想要的。
为了允许我们的包更改Text
,我们必须添加以下节点:
<CommandFlag>TextChanges</CommandFlag>
现在,如果我们运行VSPackage,它应该按预期工作!
如果您希望允许更改菜单项的Visibility
(这是我最初的目标),那么您可以使用以下CommandFlag
:
<CommandFlag>DynamicVisibility</CommandFlag>
有一个full list of command flags here,其中包含对其内容的描述。
答案 1 :(得分:9)
您可以使用:
,而不是直接使用musefan答案中提到的guid [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids.SolutionExists)]
有关所有guid常量,请参阅:UIContextGuids Class。