.NET Forum / Visual Studio.NET / Extensibility / July 2006
Remove Menubar on OnDisconnect of Addin?
|
|
Thread rating:  |
JimGraham - 06 Jul 2006 18:45 GMT Hi
I'm looking for the proper way to remove my addin's menu bar from the OnDisconnect method. I want that when the addin is unloaded via the Addin manager, that its commands and the menubar on which they sit disappear. I've got this working on the first pass. But when I reload the addin the second time, I get multiple copies of my menubar. Sometimes the menubar has the correct name, sometimes it has a different name (I think depending on the index of where I insert the menubar on its parent menubar).
I suspect I'm not removing my menubar correctly. Is there a 'correct' way to do this?
I have some sample code below that shows my problem. Here I am adding an "AddinTemplate" Menubar to the "MenuBar->Build" menu. It has 2 commands (FooAddinTemplate, BarAddinTemplate). If I add the addin via the Manager, it looks good. THen removing it also looks good (my menubar goes away). On adding it back a 2nd time causes problems; I get 2 versions of my menubar.
Here's the OnConnection and OnDisconnection methods
[code] public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom) { _applicationObject = (DTE2)application; _addInInstance = (AddIn)addInInst; if(connectMode == ext_ConnectMode.ext_cm_UISetup || connectMode == Extensibility.ext_ConnectMode.ext_cm_Startup || connectMode == Extensibility.ext_ConnectMode.ext_cm_AfterStartup )
{ object []contextGUIDS = new object[] { }; Commands2 commands = (Commands2)_applicationObject.Commands;
//Place the command on the Build Menu Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"]; CommandBar BuildCommandBar = ((CommandBarPopup)menuBarCommandBar.Controls["Build"]).CommandBar;
try { //Add a command to the Commands collection: Command foo_command = commands.AddNamedCommand2(_addInInstance, "FooAddinTemplate", "FooAddinTemplate", "Executes the command for AddinTemplate", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton); Command bar_command = commands.AddNamedCommand2(_addInInstance, "BarAddinTemplate", "BarAddinTemplate", "Executes the command for AddinTemplate", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton); CommandBar addinCmdBar = (CommandBar)commands.AddCommandBar("AddinTemplate", vsCommandBarType.vsCommandBarTypeMenu, BuildCommandBar, BuildCommandBar.Controls.Count); CommandBarControl addinFooControl = (Microsoft.VisualStudio.CommandBars.CommandBarControl)foo_command.AddControl(addinCmdBar, 1); CommandBarControl addinBarControl = (Microsoft.VisualStudio.CommandBars.CommandBarControl)bar_command.AddControl(addinCmdBar, 2); } catch(System.ArgumentException) { ; } } }
public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom) { if (disconnectMode != ext_DisconnectMode.ext_dm_UserClosed && disconnectMode != ext_DisconnectMode.ext_dm_HostShutdown) return;
CommandBar cmdBar; try { while ((cmdBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)this._applicationObject.CommandBars)["AddinTemplate"]) != null) { foreach (CommandBarControl objCBC in cmdBar.Controls) { try { objCBC.Delete(null); } catch (System.Exception e) {; } }
try { this._applicationObject.Commands.RemoveCommandBar(cmdBar); } catch (System.Exception e) { ; } } } catch { ; }
// Remove all Commands Command cmd = null; try { cmd = this._applicationObject.Commands.Item("AddinTemplate.Connect.FooAddinTemplate", -1); cmd.Delete(); cmd = this._applicationObject.Commands.Item("AddinTemplate.Connect.BarAddinTemplate", -1); cmd.Delete(); } catch { ; } }
[/code]
Carlos J. Quintero [VB MVP] - 07 Jul 2006 08:33 GMT Hi Jim,
Some basics about permanent / temporary UI elements and ext_ConnectMode.ext_cm_UISetup:
HOWTO: Adding buttons, commandbars and toolbars to Visual Studio .NET from an add-in.
HOWTO: Removing commands and UI elements during Visual Studio .NET add-in uninstallation.
at:
Resources about Visual Studio .NET 2002/2003 and Visual Studio 2005 extensibility http://www.mztools.com/resources_vsnet_addins.htm
 Signature Best regards,
Carlos J. Quintero
MZ-Tools: Productivity add-ins for Visual Studio You can code, design and document much faster: http://www.mztools.com
> Hi > [quoted text clipped - 122 lines] > > [/code] JimGraham - 07 Jul 2006 14:33 GMT Hi Carlos
Thanks for the help. I looked at your detailed set of articles before I posted. The first article you mentioned (dealing with temporary commands and menus) seemed relevant, but I can't make it work for me, for the menubar
In VS 2005, I try something like
//' Add a new toolbar with a button on it CommandBar addinCmdBar = _applicationObject.CommandBars.Add("AddinTemplate", MsoBarPosition.msoBarTop, null, true);
First, Intellisense indicates that there is no "Add" method. THen I get a compiler error "Object does not contain a definition for 'Add'
Has something changed between VS 2003 and 2005. I tried casting to the DTE object instead of the DTE2 object and get the same error.
Any help is appreciated.
- jim
> Hi Jim, > [quoted text clipped - 149 lines] > > > > [/code] Carlos J. Quintero [VB MVP] - 10 Jul 2006 09:12 GMT Hi Jim,
On the one hand, VS 2005 introduced a change in the reference used for Office commandbars and as an unfortunate consequence, some methods that previously returned a CommandBar or CommandBars now return an Object, so you need to do a manual cast to CommanBars:
CommandBars colCommandBars;
colCommandBars = (CommandBars) _applicationObject.CommandBars; // Object -> CommandBars
colCommandBars.Add("AddinTemplate", msoBarPosition.msoBarTop, null, true);
That should fix the missing Add problem.
On the other hand, see my articles closely. Without reading your whole code, this line is bad:
if(connectMode == ext_ConnectMode.ext_cm_UISetup || connectMode == Extensibility.ext_ConnectMode.ext_cm_Startup || connectMode == Extensibility.ext_ConnectMode.ext_cm_AfterStartup )
You should NEVER do the same things in the ext_ConnectMode.ext_cm_UISetup than in the Startup/AfterStartup. Decide if you want permanent UI (ext_ConnectMode.ext_cm_UISetup) using Commands.AddCommandBar, removable on add-in uninstallation, or temporary UI Startup/AfterStartup using CommandBars.Add, removable on add-in disconnection.
It happens that ext_ConnectMode.ext_cm_UISetup only fires once in the whole life of an add-in and there should be used to create commands and permanent UI (if you decide that you want to use permanent UI). It happens too that add-in projects created by the VS 2005 add-in wizard, on the contrary to VS.NET 2003, adds a /resetaddin <AddInProgID> to the property pages of the project. This /resetaddin causes that ext_ConnectMode.ext_cm_UISetup is fired on each debug session, which may confuse you. I will try to update my article(s) to explain this.
The bottom line if you want your UI to be removed when the add-in is unloaded:
- When connectMode == ext_ConnectMode.ext_cm_UISetup, create the commands if they don't already exist. Nothing else. Remove the commands on add-in uninstallation.
- When connectMode == Extensibility.ext_ConnectMode.ext_cm_Startup || connectMode == Extensibility.ext_ConnectMode.ext_cm_AfterStartup, create the toolbars, commandbars, menus and buttons of your add-in. Remove them on disconnection.
 Signature Best regards,
Carlos J. Quintero
MZ-Tools: Productivity add-ins for Visual Studio You can code, design and document much faster: http://www.mztools.com
Hi Carlos
Thanks for the help. I looked at your detailed set of articles before I posted. The first article you mentioned (dealing with temporary commands and menus) seemed relevant, but I can't make it work for me, for the menubar
In VS 2005, I try something like
//' Add a new toolbar with a button on it CommandBar addinCmdBar = _applicationObject.CommandBars.Add("AddinTemplate", MsoBarPosition.msoBarTop, null, true);
First, Intellisense indicates that there is no "Add" method. THen I get a compiler error "Object does not contain a definition for 'Add'
Has something changed between VS 2003 and 2005. I tried casting to the DTE object instead of the DTE2 object and get the same error.
Any help is appreciated.
- jim
Carlos J. Quintero [VB MVP] wrote:
> Hi Jim, > [quoted text clipped - 151 lines] > > > > [/code] Carlos J. Quintero [VB MVP] - 10 Jul 2006 10:13 GMT > I will try to update my article(s) to explain this. Done. See the updated:
HOWTO: Adding buttons, commandbars and toolbars to Visual Studio .NET from an add-in
http://www.mztools.com/articles/2005/MZ003.htm
 Signature Best regards,
Carlos J. Quintero
MZ-Tools: Productivity add-ins for Visual Studio You can code, design and document much faster: http://www.mztools.com
JimGraham - 11 Jul 2006 17:15 GMT Hi Carlos
You're a genius. Fixing the explicit cast from Object -> CommandBars solved all my problems. My code is about 100 lines shorter and does what I want it to do. I now only load on _Startup or _AfterStartup.
Thanks again.
- jim
> > I will try to update my article(s) to explain this. > [quoted text clipped - 14 lines] > You can code, design and document much faster: > http://www.mztools.com
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|