【问题标题】:Why does Visual Studio 2008 forget where to dock my add-in's window pane?为什么 Visual Studio 2008 忘记将我的加载项窗口窗格停靠在哪里?
【发布时间】:2008-11-19 11:05:02
【问题描述】:

我为 Visual Studio 2008 编写了一个简单的加载项,它打开了一个可停靠的窗口窗格。

You can download the source and a binary installer by clicking here.

加载项的性质意味着它理想情况下会停靠在您编辑源的位置旁边。但有时,在某些安装中,它不会保持停靠。您运行 VS,停靠我的窗格,关闭 VS,重新启动 VS,然后挂掉它 - 窗格再次浮动。在某些机器上,我每次都必须重新对接。

但在其他安装中,无论我把它永远放在哪里,它都会保持停靠。我最初认为这可能是 Vista 和 XP 之间的差异,但现在我有报告称它在 XP 上也将失效。

从我读到的内容(以及它有时保持停靠的事实),我得到的印象是 VS 应该负责为我保存停靠状态。但它没有这样做。而同一 VS 安装上的其他插件则没有这个问题。所以我必须做些什么来改善这种情况。

我怀疑我的代码中唯一相关的部分是:

public class Connect : IDTExtensibility2
{
    private static DTE2 _applicationObject;
    private AddIn _addInInstance;
    private static CodeModelEvents _codeModelEvents;

    public static DTE2 VisualStudioApplication
    {
        get { return _applicationObject; }
    }

    public static CodeModelEvents CodeModelEvents
    {
        get { return _codeModelEvents; }
    }

    public static event EventHandler SourceChanged = delegate { };

    public void OnConnection(object application, 
           ext_ConnectMode connectMode, object addInInst, ref Array custom)
    {
        _applicationObject = (DTE2)application;
        _addInInstance = (AddIn)addInInst;
    }

    public void OnStartupComplete(ref Array custom)
    {
        try
        {
            Events2 events = (Events2)_applicationObject.Events;
            _codeModelEvents = events.get_CodeModelEvents(null);

            object objTemp = null;

            Windows2 toolWins = (Windows2)_applicationObject.Windows;

            Window toolWin = toolWins.CreateToolWindow2(
                _addInInstance, GetType().Assembly.Location, "Ora.OraPane", "Ora", 
                "{DC8A399C-D9B3-40f9-90E2-EAA16F0FBF94}", ref objTemp);
            toolWin.Visible = true;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Exception: " + ex.Message);
        }
    }

    public void OnBeginShutdown(ref Array custom) { }

    public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom) { }

    public void OnAddInsUpdate(ref Array custom) { }
}

(MSDN 文档建议应在 OnConnection 中创建窗口,但如果我这样做,则窗口大多不会出现。)

【问题讨论】:

    标签: visual-studio visual-studio-2008 add-in visual-studio-addins docking


    【解决方案1】:

    我在使用 TeamReview (http://www.codeplex.com/TeamReview) 时遇到了一些相同的对接问题。我不能说为什么会发生这种情况,但我可以帮助您指出始终在 OnStartupComplete 中记录您的窗口的代码。如果你有一个特定的位置,你希望它在你可以在创建你的 toolWin 之后和调用 Visible 属性之前将它链接到一个框架内。您必须检查哪些常量适合 CreateLinkedWindowFrame 和 SetKind 方法的条件。此外,您可能希望将窗口链接到 MainWindow 以外的其他内容,例如 SolutionExplorer

    EnvDTE80.Window2 frame = toolWins.CreateLinkedWindowFrame(toolWin, toolWin, vsLinkedWindowType.vsLinkedWindowTypeTabbed);
    
    
    frame.SetKind(EnvDTE.vsWindowType.vsWindowTypeToolWindow);
    
    
    _applicationObject.MainWindow.LinkedWindows.Add(frame);
    
    frame.Activate();
    

    此示例类似于:http://www.codeplex.com/TeamReview/SourceControl/changeset/view/16102# 2008 -> TeamReview -> Command -> ShowReplayWindowCommand.cs -> ShowForm()

    这里是a good Microsoft example,用于将输出窗口、命令窗口和解决方案资源管理器链接在一起。然后,它操纵这些链接窗口的宽度和高度,最后将它们全部从链接窗口框架中取消停靠。

    【讨论】:

    • 感谢您提供如此详细的有用答案。我真正想要的是让我的窗格准确地保持在用户放置它的位置,但我想我必须将一些近似于它的东西拼凑在一起。
    • 在这里开发插件。这篇文章非常有帮助。如果它没有取消我的投票,会投票两次:P。
    • 这个答案很有用,但需要(大量)工作才能使工具窗口保持停靠在用户上次离开的位置。 Juozas Kontvainis 的答案要简单得多,并且对我有用(在尝试了许多其他解决方案后,都没有奏效)。
    【解决方案2】:

    我和作者有同样的问题。我注意到 Visual Studio 2005 仅在使用调试的会话之后“忘记”工具窗口位置。

    接受的答案没有多大帮助,因为工具窗口总是停靠在底部。我真的希望用户能够选择他们想要停靠的位置,并通过简单地停靠在他们喜欢的位置来保存他们的偏好。

    【讨论】:

    • 我同意。如果有人有更好的建议,我会接受!
    【解决方案3】:

    这对我有帮助。我使用 Visual Studio 2005,但这也可能对您有所帮助。

    public void OnBeginShutdown(ref Array custom)
    {
         if (_toolWin != null)
              _toolWin.Visible = false;
    }
    

    【讨论】:

    • 当您的工具窗口被取消停靠时,您是否注意到任何模式?对我来说,问题在于调试,即如果我启动 Visual Studio 并且没有开始调试,我的插件工具窗口工作正常,如果我调试了某些东西 - 它将在下一个会话中取消停靠。
    • +1 这似乎对我也有用,我使用的是 Visual Studio 2008。我的猜测是,当你使工具窗口不可见时,VS 会保存它的大小和位置。我只需要在使其不可见之前还保存工具窗口的可见性状态。
    【解决方案4】:

    将工具窗口可见性设置为 false 效果非常好。谢谢JK。

    为了回答 JK 关于调试后取消停靠的问题,我想知道项目调试属性中的 devenv.exe /resetaddin 开关是否会导致这种情况发生。它肯定会重置插件创建的所有其他内容。

    想法:当您创建插件项目时,/resetaddin 开关会自动添加到调试配置中。我通常在 /resetaddin 命令中在类名的字体上加上一个无效字符,例如“x”,这样当我们确实需要硬重置时,可以通过删除 x 轻松地重新启用它。每次调试时通常不需要重置!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      相关资源
      最近更新 更多