为什么Visual Studio 2008会忘记如何停靠我的插件窗格?

7
我为Visual Studio 2008编写了一个简单的插件,它可以打开可停靠的窗口面板。
您可以通过点击此处下载源代码和二进制安装程序。
这个插件的特性意味着它理想情况下会一直停靠在您编辑源代码的地方。但有时,在某些安装中,它不会停靠。你运行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中创建窗口,但如果我这样做,窗口大多数情况下都不会出现。)
4个回答

9

我曾经在使用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()类似。
这里有一个很好的微软示例,将输出窗口、命令窗口和解决方案资源管理器连接在一起。然后它操纵这些链接窗口的宽度和高度,并最终将它们全部从链接窗口框架中拆离出来。

感谢您提供如此详细和有帮助的答案。我真正想要的是我的窗格保持在用户放置它的位置,但我想我必须编写一些代码来近似实现它。 - Daniel Earwicker
在这里开发一个addin。这篇文章非常有帮助。如果它没有取消我的投票,我会投两次的:P。 - Maxime Rouiller
这个答案很有用,但需要(很多)更多的工作才能让工具窗口停留在用户上次离开的位置。Juozas Kontvainis的答案更简单,对我有效(在尝试了许多其他解决方案之后,都没有起作用)。 - Polyfun

1

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

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


我同意。如果有更好的建议,我会接受它! - Daniel Earwicker

1

这是对我有帮助的方法。我使用的是Visual Studio 2005,但这也可能对你有所帮助。

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

1
你是否注意到你的工具窗口在取消停靠时出现任何模式?对我来说,问题出在调试方面,也就是说如果我启动Visual Studio而没有启动调试,我的插件工具窗口能够正常工作,但如果我要调试一些东西,下次会话它就会被取消停靠。 - Juozas Kontvainis
+1 这对我也有效,我正在使用 Visual Studio 2008。我猜当你将工具窗口设为不可见时,VS 会保存其大小和位置。我只需要在将其设为不可见之前也保存工具窗口的可见状态即可。 - Polyfun

0

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

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接