Search code examples
c#visual-studiovisual-studio-addins

Enable / Disable commands depending on executed commands


I've got this problem for a while now and I cannot find a solution anywhere. I'm currently writing an add-in (using C#) for Visual Studio 2010. I've added a new menu to the VS menu bar. Within this menu there are several commands e.g. "login" and "logout". The behavior I'd like to enforce would be that both commands are visible, but only "login" would be initially enabled and "logout" initially disabled.

I achieve this through the following code in the OnConnection() method:

    LoginCommand = applicationObject.Commands.AddNamedCommand(
                           addInInstance, 
                           LOGIN_NAME,
                           LOGIN_CAPTION,  
                           LOGIN_TOOLTIP, 
                           true, 59, 
                           ref contextUIGuids,
                           (int)(vsCommandStatus.vsCommandStatusSupported | 
                                vsCommandStatus.vsCommandStatusEnabled)
                        );

    LogoutCommand = applicationObject.Commands.AddNamedCommand(
                            addInInstance, 
                            LOGOUT_NAME,
                            LOGOUT_CAPTION, 
                            LOGOUT_TOOLTIP, 
                            true, 59, 
                            ref contextUIGuids,
                            (int)(vsCommandStatus.vsCommandStatusSupported)
                        );

When I issue the "login" command and I've successfully logged in, I want it the other way around so that the "login" command is disabled in the menu and "logout" is enabled - until I log out.

And this is where I'm stuck. I just don't know where and how exactly to implement the state switching of the commands. I guess I have to handle this in the QueryStatus() method, but Microsoft's documentation on this topic is rather less helpful or eye opening.


Solution

  • Alright, I figured out a solution, though I'm not quite sure if it's elegant. After a command (e.g. LoginCommand) gets executed the QueryStatus() method gets called multiple times, but with a different value for commandName.

    public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText)
        {
            if(neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
            {
                if (loginOkay == 0)
                {
                    if (commandName == addInInstance.ProgID + "." + LOGIN_NAME)
                    {
                        status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported;
                    }
                    if (commandName == addInInstance.ProgID + "." + LOGOUT_NAME ||
                        commandName == addInInstance.ProgID + "." + LOCK_NAME ||
                        commandName == addInInstance.ProgID + "." + UNLOCK_NAME ||
                        commandName == addInInstance.ProgID + "." + CHECKIN_NAME ||
                        commandName == addInInstance.ProgID + "." + CHECKOUT_NAME)
                    {
                        status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
                    }
                }
                else if (loginOkay == 1)
                {
                    if (commandName == addInInstance.ProgID + "." + LOGIN_NAME)
                    {
                        status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
                    }
                    if (commandName == addInInstance.ProgID + "." + LOGOUT_NAME ||
                        commandName == addInInstance.ProgID + "." + LOCK_NAME ||
                        commandName == addInInstance.ProgID + "." + UNLOCK_NAME ||
                        commandName == addInInstance.ProgID + "." + CHECKIN_NAME ||
                        commandName == addInInstance.ProgID + "." + CHECKOUT_NAME)
                    {
                        status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported;
                    }
                }
                else
                {
                    status = vsCommandStatus.vsCommandStatusUnsupported;
                }
            }
        }
    

    Anyway, thank you Schaliasos for your help. I'd love to vote your answer up, but since I'm lagging the reputation points I can't.