【问题标题】:Enable / Disable commands depending on executed commands根据执行的命令启用/禁用命令
【发布时间】:2012-06-14 10:05:09
【问题描述】:

这个问题我已经有一段时间了,我无法在任何地方找到解决方案。 我目前正在为 Visual Studio 2010 编写一个加载项(使用 C#)。 我在 VS 菜单栏中添加了一个新菜单。在这个菜单中有几个命令,例如“登录”和“注销”。 我想强制执行的行为是这两个命令都是可见的,但最初只会启用“登录”而最初禁用“注销”。

我通过 OnConnection() 方法中的以下代码实现了这一点:

    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)
                        );

当我发出“登录”命令并成功登录时,我希望它相反,以便在菜单中禁用“登录”命令并启用“注销” - 直到我注销。

这就是我卡住的地方。我只是不知道在哪里以及如何确切地实现命令的状态切换。 我想我必须在 QueryStatus() 方法中处理这个问题,但是微软关于这个主题的文档不太有用或令人大开眼界。

【问题讨论】:

    标签: c# visual-studio visual-studio-addins


    【解决方案1】:

    您需要将AfterExecute 事件添加到您的LoginCommand 事件中。在OnConnection 方法中添加以下内容:

    Events events = (EnvDTE.Events) applicationObject.Events;
    CommandEvents LoginEvent = events.get_CommandEvents(LoginCommand.Guid, LoginCommand.ID);
    cmdEvent.AfterExecute += new _dispCommandEvents_AfterExecuteEventHandler(LoginEvent_AfterExecute);
    

    并创建LoginEvent_AfterExecute 方法:

    private void LoginEvent_AfterExecute(string guid, int id, object customIn, object customOut)
    {
        //Delete the LoginCommand from the commands2 object and recreate it
        LoginCommand.Delete();
    
        LoginCommand = applicationObject.Commands.AddNamedCommand(
                           addInInstance, 
                           LOGIN_NAME,
                           LOGIN_CAPTION,  
                           LOGIN_TOOLTIP, 
                           true, 59, 
                           ref contextUIGuids,
                           (int)(vsCommandStatus.vsCommandStatusSupported)
                        );
    
        //Delete the LogoutCommand and recreate it
        LogoutCommand.Delete();  
    
        LogoutCommand = applicationObject.Commands.AddNamedCommand(
                            addInInstance, 
                            LOGOUT_NAME,
                            LOGOUT_CAPTION, 
                            LOGOUT_TOOLTIP, 
                            true, 59, 
                            ref contextUIGuids,
                            (int)(vsCommandStatus.vsCommandStatusSupported| 
                                vsCommandStatus.vsCommandStatusEnabled)
                        );
    
    }
    

    资源:

    【讨论】:

    • 谢谢,这确实帮助了我,但我的真正意思是如何实际更改命令的状态,以便启用或禁用它们。
    • 请再次检查。不确定它是否有效,我没有测试过。
    • 我已经实现了此处发布的LoginEvent_AfterExecute() 方法,但出现以下错误:“LoginEvent_AfterExecute”没有重载与委托“EnvDTE._dispCommandEvents_AfterExecuteEventHandler”匹配。此时出现此错误:LoginEvent.AfterExecute += new _dispCommandEvents_AfterExecuteEventHandler(LoginEvent_AfterExecute); 很抱歉我缺乏 C# 知识。但是我在互联网上找不到任何有用的东西。再次感谢您的帮助!
    • 没什么好担心的。请再次检查。我还发布了一些有用的链接。我认为第一个是您需要的,虽然它是用 VB 编写的,但它会对您有所帮助。
    【解决方案2】:

    好的,我想出了一个解决方案,虽然我不太确定它是否优雅。 在执行命令(例如LoginCommand)后,QueryStatus() 方法被多次调用,但 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;
                }
            }
        }
    

    无论如何,谢谢Schaliasos 的帮助。我很想投票给你的答案,但由于我落后于声誉点,我不能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-11
      • 1970-01-01
      相关资源
      最近更新 更多