在Visual Studio窗格中添加自定义编辑器窗口

23

我的问题

我正在尝试构建一个Visual Studio扩展程序,它允许按函数而不是按文件进行编辑。我基本上想以类似于Microsoft Debugger Canvas的方式显示代码。

我想知道如何在单个窗口中托管多个Visual Studio编辑器(我认为这些窗口正在实现IVsWindowFrame)。我需要的功能如下所示:

Microsoft Debugger Canvas

Each editor window retains typical functionality and interacts with third-party extensions as expected. (For example, VsVim functions correctly within these windows).

我尝试过的事情

我花了将近两周的时间研究和尝试这些东西,但是我很难弄清楚我将要使用哪些服务、接口和类。

阅读 MSDN

首先,大部分文档讨论如何编辑单个编辑器窗口并添加装饰、标记、边距等。它没有讨论在一个窗格内生成多个编辑器的可能性。

我查看了许多我感兴趣的接口的文档,包括IVsTextBufferIVsTextViewIVsInvisibleEditor。不幸的是,我无法让其中一些接口良好地协同工作。

在此基础上,通常出色的MSDN在这个领域极其缺乏。许多接口仅包含成员列表,甚至没有关于预期使用和功能的基本说明(例如IComponentModel)。
许多接口引用一组Editor Samples,但是在MSDN上无法阅读或下载代码。显然,它随Visual Studio 2005一起发布,但我没有这个版本的Visual Studio,也找不到它。
与IVsUIShell交互
我可以使用IVsUIShell.GetDocumentWindowEnum();访问所有打开的WindowFrames。 我看到有一个IVsUiShell.CreateDocumentWindow()方法,但我完全不熟悉它接受的参数,也不知道这是否是正确的路径。

我需要做什么

  1. 编程创建一个可停靠的窗格
  2. 编程将编辑器添加到此窗格中(并确保它们在Visual Studio、运行文档表等中正确注册)

编辑:

对不起,我应该详细说明我的步骤。当我说需要在运行文档表和Visual Studio中注册时,是因为我想实际编辑自定义编辑器中的原始文档。下面是Debugger Canvas中可用功能的简短示例,我正在尝试重新创建:

http://i.imgur.com/aYm8A5E.gif(我无法嵌入.gif文件)

或者:

如果有人知道我可以在Visual Studio 2005中找到包含Basic Editor Sample之类的编辑器示例,我肯定可以弄清楚这些东西。MSDN文档没有关于这些接口的代码示例,这使我的工作非常困难。


您想要的示例附带于Visual Studios SDK中。由于它们没有显示任何更新版本,我预计最新版本将具有相同的示例。 - tinstaafl
没有Visual Studio 2012 SDK示例,但有2010示例。我已经查看了所有示例,但没有一个是我提供的VS 2005链接中提到的那些示例。我相信2010示例旨在突出显示他们为该版本的Visual Studio添加的WPF界面。 - JoshVarty
嗨,乔什。我在寻找与你类似的扩展时发现了你的问题(在阅读《代码整洁之道》后)。你有没有找到或构建出替代 Debugger Canvas 的方法?顺便说一下,我刚刚意识到,你就是 Shotgun Debugging Roslyn 教程背后的那个家伙 - 感谢你的教程 :-) - Ivan Koshelev
我利用在这里学到的信息和我的一个朋友一起建立了http://codeconnect.io。然而,它是用于探索代码而不是调试它。谢谢,很高兴你觉得它们有帮助 :) - JoshVarty
3个回答

12

Git源代码控制提供程序是一个开源扩展,包括一个工具窗格,该窗格将标准编辑器嵌入自定义WPF工具窗口中。如果我想在某个自定义位置托管编辑器窗口,则可以将此代码用作任何Visual Studio 2010+扩展的参考。

  • PendingChangesView.xaml包含名为DiffEditorContentControl,其内容将作为编辑器。
  • PendingChangesView.xaml.cs包括一个名为ShowFile的方法,该方法调用一个方法来创建编辑器控件,并将结果分配为DiffEditor的内容。
  • ToolWindowWithEditor.cs包括一个名为SetDisplayedFile的方法,该方法返回一个Tuple<Control, IVsTextView>接口,该接口提供对可添加到ContentControlControl以及文本视图的IVsTextView的访问权限。这个方法承担了重要的工作。

请注意,SetDisplayedFile方法包括几行具有以下形式的代码:

textViewHost.TextView.Options.SetOptionValue({name}, {value});
这些代码行对于Git源代码控制提供者至关重要,例如移除边距和使窗口只读。可用的选项很多,因此您需要查看 DefaultTextViewOptionsDefaultTextViewHostOptions 的文档,以应用适合您特定扩展的选项。

这看起来非常有前途,至少应该让我了解这个InvisibleEditor管理器。我会在本周末更深入地研究这段代码。 - JoshVarty

2
我实际上还没有查看@280Z28(为什么这个用户名?)发布的文件。我曾经在Visual Studio编辑器上工作,你正在尝试做的事情有多个方面需要你分别解决:
  • 在单个IVsWindowFrame中托管多个命令目标(这意味着您将在Visual Studio Shell的视角下在同一窗格中拥有不同的元素,并且每个元素都需要有自己的命令处理。考虑这样一种情况:您将插入符号放置在一个小型编辑器中,然后想使用Ctrl+Z撤消,过了一会儿,您又将插入符号放置到另一个小型编辑器中并执行相同的操作。尽管WPF和Win32焦点仍然位于同一窗口框架内(从Visual Studio Shell的视角来看),但命令需要路由到不同的组件。
  • 使用正在显示另一个文档部分的编辑器。这里将成为您的朋友的机制位于projection namespace中。投影基本上允许您将缓冲区(或缓冲区的一部分)投影到视图中。省略缓冲区是将一个源缓冲区投影到目标视图的特殊情况,同时隐藏缓冲区的区域(这很可能是您想要的)。 cshtml文件中发生的情况就是一个投影缓冲区的例子。在这种情况下,有一个包含所有C#代码的缓冲区,一个包含所有javascript的缓冲区,以及一个包含html的缓冲区,并且每个编译器都从该缓冲区中工作,但最终用户只看到所有这些缓冲区的投影,只显示相关部分(例如C#导入语句被省略,即使它们存在于实际的C#缓冲区中)。
  • 管理运行文档,以便在小型编辑器中进行编辑时,真实文档会变脏。您需要处理父文件已经在RDT中打开的情况,在这种情况下,当更改时,您需要将同一文档标记为已修改,并且还需要处理文档未打开的情况,在这种情况下,您需要在RDT中创建一个新条目。
另外,请发布到Visual Studio论坛,那里有人定期检查论坛并将问题路由到相应的开发人员。
一般来说,当涉及到编辑器时,避免使用任何传统的界面(任何不使用MEF的东西),因此不应将Visual Studio 2005的样例用作参考点。
如果您足够关心并且在西雅图,您可以尝试以MVP身份前往校园。有些日子,您可以来到校园,各种团队成员会拿起笔记本电脑来到您的会议室,您可以一起调试代码或者进行编码(同时具有访问调试符号等内容的权限)。
最后但并非最不重要的,请联系code canvas的人们,我相信他们已经解决了您所面临的许多问题。

谢谢回复,我已经在论坛上发布了:http://social.msdn.microsoft.com/Forums/vstudio/en-US/dc219071-0f33-4ea3-9a3a-b773ce2d391b/vs-package-add-custom-editor-windows-to-visual-studio-window-panes 我也联系了代码画布的人,但没有得到回复。我不在西雅图,但一个正在处理这个问题的朋友很快就会去那里,我会让他知道的。谢谢你的建议! - JoshVarty
不用谢。我想告诉你一个电子邮件地址,让你发邮件,但我无法找到你的电子邮件地址(我不确定是否可以公开分享此电子邮件地址)。在你的博客上放置你的联系信息吧! :) 发送邮件至 ameen@triangle.io,这样我就能与你分享了。 - Ameen

1
您需要使用ProvideToolWindow属性向您的包扩展注册一个工具窗口。以下文章包含有关如何在工具窗口中托管编辑器的所有必要信息:http://bit.ly/9VWxPR 请查看WpfTextViewHost类;该文章解释了这种类型实际上是一个UIElement,因此我想可以托管多个它的实例...

1
可以将它放在工具窗格中,但不是必须的。 - Sam Harwell

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