visual studio shell custom command



I am creating a Visual Studio Package (this is my first time) and my end goal is to create a context-menu item for the solution explorer that only works on certain file types. (I thought this would be a common thing, but didn't find any decent tutorials on it, so if you know any please let me know)

I followed a simple MSDN guide to create an item in the toolbar first (I forget where is was to link it) and this worked fine.

Then I found a way to move it to the Solution Explorer context menu. This was achieved by manipulating the .vsct file and having an element like this:

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

That probably doesn't matter, but I am trying to set the scene.

Now, because I want to only show the item for certain file types, I need to find a way to check the file when the right-click button is pressed. Cutting a long search short, I found this and ended up with the following code:

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";
}

In the above example I am just trying to set the text to try and prove it works, I know there is a Visible property but I want this step to work first. The BeforeQueryStatus event is fired, and debugging shows the code executing as expected. However, there is no change in the context menu item, it stays with the original text.

What am I missing here? Why is it not updating?



I am creating a Visual Studio Package (this is my first time) and my end goal is to create a context-menu item for the solution explorer that only works on certain file types. (I thought this would be a common thing, but didn't find any decent tutorials on it, so if you know any please let me know)

I followed a simple MSDN guide to create an item in the toolbar first (I forget where is was to link it) and this worked fine.

Then I found a way to move it to the Solution Explorer context menu. This was achieved by manipulating the .vsct file and having an element like this:

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

That probably doesn't matter, but I am trying to set the scene.

Now, because I want to only show the item for certain file types, I need to find a way to check the file when the right-click button is pressed. Cutting a long search short, I found this and ended up with the following code:

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";
}

In the above example I am just trying to set the text to try and prove it works, I know there is a Visible property but I want this step to work first. The BeforeQueryStatus event is fired, and debugging shows the code executing as expected. However, there is no change in the context menu item, it stays with the original text.

What am I missing here? Why is it not updating?


OK, so I have finally found a solution to this problem, there are a couple of things that you need to do...

STEP 1:

We need to specify that the VSPackage should "auto-load", we do this so that the code will execute when the ContextMenu is shown, because normally the VSPackage would not initialise before the UI has been shown (i.e. the menu item has been clicked). To do this we add an attribute to the Package class, like so:

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

You may wonder what that GUID value is, well in this case it represents the UICONTEXT_SolutionExists constant, which means the the package will auto-load when a solution exists (so when we create a new one or load one). I got this information from here, as you might be able to tell there are a number of different VSConstants that could be used.

Here are a couple more resources that list other GUID values that can be used:

STEP 2:

Now that the BeforeQueryStatus code is executing at the correct place, it is still confusing as to why the code doesn't actually change anything (in my question I try to change the Text). Well, the answer is, because we need to give the package permission to do so (at least that's the way I see it as being).

To do this we must edit the .vsct file. Inside there we can find a Buttons element, inside which should be our ContextMenu Button. By default there are some comments which mention the use of the CommandFlag node - this is what we want.

In order to give permission for our package to change the Text we must add the following node:

<CommandFlag>TextChanges</CommandFlag>

Now, if we run the VSPackage it should all work as expected!

If you are looking to allow permission to change the Visibility of the menu item (which was my original aim) then you can use the following CommandFlag:

<CommandFlag>DynamicVisibility</CommandFlag>

There is a full list of command flags here, with descriptions on what they do.


I am creating a Visual Studio Package (this is my first time) and my end goal is to create a context-menu item for the solution explorer that only works on certain file types. (I thought this would be a common thing, but didn't find any decent tutorials on it, so if you know any please let me know)

I followed a simple MSDN guide to create an item in the toolbar first (I forget where is was to link it) and this worked fine.

Then I found a way to move it to the Solution Explorer context menu. This was achieved by manipulating the .vsct file and having an element like this:

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

That probably doesn't matter, but I am trying to set the scene.

Now, because I want to only show the item for certain file types, I need to find a way to check the file when the right-click button is pressed. Cutting a long search short, I found this and ended up with the following code:

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";
}

In the above example I am just trying to set the text to try and prove it works, I know there is a Visible property but I want this step to work first. The BeforeQueryStatus event is fired, and debugging shows the code executing as expected. However, there is no change in the context menu item, it stays with the original text.

What am I missing here? Why is it not updating?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值