将自定义编辑器窗口添加到Visual Studio窗口窗格

时间:2013-07-22 00:12:38

标签: c# visual-studio editor mef visual-studio-extensions

我的问题

我正在尝试构建一个Visual Studio扩展,允许在每个函数的基础上编译代码,而不是基于每个文件。我基本上试图以与Microsoft Debugger Canvas类似的方式显示代码。

我想知道如何在一个窗口中托管多个Visual Studio编辑器(我相信windows正在实现IVsWindowFrame)。我所追求的功能如下所示:

Microsoft Debugger Canvas

每个编辑器窗口都保留了典型功能,并按预期与第三方扩展进行交互。 (例如,VsVim在这些窗口中正常运行)。

我尝试过什么

我花了将近两周时间研究和尝试这些东西,并且我在确定我将使用哪些服务,接口和类时遇到了很多麻烦。

通过MSDN阅读

首先,大多数documentation讨论了如何编辑单个编辑器窗口以及添加装饰,标签,边距等。它没有讨论在窗口窗格中生成多个编辑器的可能性。

我查看了我感兴趣的大量界面的文档,包括IVsTextBufferIVsTextViewIVsInvisibleEditor。不幸的是,我不能让这些接口中的一些很好地一起玩。

最重要的是,通常优秀的MSDN在这方面非常缺乏。许多接口只包含一个成员列表,甚至没有关于预期用途和功能的基本注释。 (例如IComponentModel)。

许多接口都引用了一组Editor Samples,但无法在MSDN上读取或下载代码。显然它随Visual Studio 2005一起发布,但我没有这个版本的Visual Studio,也找不到它。

与IVsUIShell交互

我可以使用IVsUIShell.GetDocumentWindowEnum();访问所有打开的WindowFrame 我看到有IVsUiShell.CreateDocumentWindow()方法,但我完全不熟悉它接受的参数,或者这是否是正确的路径。

我需要做什么

  1. 以编程方式创建可停靠的窗格
  2. 以编程方式将编辑器添加到此窗口窗格。 (并确保它们在Visual Studio,正在运行的文档表等中正确注册)。
  3. 修改

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

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

    可替换地:

    如果有人知道我在哪里可以找到Visual Studio 2005附带的编辑器示例,例如Basic Editor Sample,我相信我可以解决这个问题。 MSDN文档没有关于这些接口的代码示例,这使我的工作非常困难。

3 个答案:

答案 0 :(得分:12)

Git Source Control Provider是一个开源扩展,包括一个工具窗格,它将标准编辑器作为控件嵌入到自定义WPF工具窗口中。我会使用此代码作为任何Visual Studio 2010+扩展的参考,我想在某个自定义位置托管编辑器窗口。

  • PendingChangesView.xaml包含名为ContentControl的{​​{1}},其内容将是编辑。
  • PendingChangesView.xaml.cs包含方法DiffEditor,该方法调用方法来创建编辑器控件,并将结果指定为ShowFile的内容。
  • ToolWindowWithEditor.cs包含一个方法DiffEditor,该方法返回SetDisplayedFile界面,该界面提供对Tuple<Control, IVsTextView>的访问权限,该Control可以添加到ContentControl以及文本视图的IVsTextView这种方法很重要。

请注意,SetDisplayedFile方法包含多行,格式如下:

textViewHost.TextView.Options.SetOptionValue({name}, {value});

这些行为Git源代码控制提供程序执行关键功能,例如删除边距并使窗口只读。有很多选项,因此您需要查看DefaultTextViewOptionsDefaultTextViewHostOptions的文档,以应用适合您特定扩展名的文档。

答案 1 :(得分:2)

我实际上没有看过@ 280Z28(为什么这个用户名?)发布的文件。我曾经在Visual Studio编辑器上工作,你想要做的事情有多个方面,你应该独立解决:

  • 在单个IVsWindowFrame中托管多个命令目标(这意味着从Visual Studio的shell的角度来看,您将在同一个窗格中拥有不同的元素,并且每个元素都需要有自己的命令处理。考虑案例你把插入符号放在其中一个迷你编辑器中并希望使用Ctrl + Z撤消,片刻之后,你将插入符号放入另一个迷你编辑器并执行相同的操作。即使WPF和Win32焦点仍然在相同的窗口框架(从Visual Studio Shell的角度来看),命令需要路由到不同的组件。
  • 使用显示其他文档部分的编辑器。这里将成为你朋友的机制在projection namespace。 Projection主要允许您将一段缓冲区(或缓冲区)投影到视图中。 Ellision缓冲区是特殊情况投影缓冲区,它从一个源缓冲区投射到目标视图,同时隐藏缓冲区的区域(这很可能是您想要的)。投影缓冲区的一个例子是cshtml文件中发生的事情。在这种情况下,有一个包含所有C#代码的缓冲区,一个包含所有javascript的缓冲区,以及一个包含html的缓冲区,每个编译器都在该缓冲区之外工作,但最终用户看到所有这些缓冲区都投影到编辑器中仅显示相关部分的视图(例如,即使它们存在于真正的C#缓冲区中,也会省略C#import语句。)
  • 管理正在运行的文档,以便在迷你编辑器中进行编辑时,真实文档会变脏。您需要处理在RDT中已经打开父文件的情况,在这种情况下,您希望在进行更改时弄脏同一文档,以及文档未打开的情况,在这种情况下您需要创建一个新条目在RDT。

另外,请发布到Visual Studio forums,有人定期查看论坛并将问题发送给相应的开发者。

一般来说,当涉及到编辑器时,请避免使用任何传统接口(任何不使用MEF的接口),因此不应将Visual Studio 2005中的示例用作参考点。

如果你足够关心并且在西雅图,你可以尝试作为MVP去校园。有几天你来到校园,不同团队的成员会抓住一台笔记本电脑来到你的会议室,你可以一起调试代码或者破解(同时可以访问调试符号,什么不是)。

最后但并非最不重要的是,联系code canvas家伙,我相信他们已经解决了您面临的许多问题。

答案 2 :(得分:1)

您需要在包裹扩展名中注册工具窗口;这可以通过ProvideToolWindow属性完成。以下文章包含有关如何在工具窗口中托管编辑器的所有必需信息:http://bit.ly/9VWxPR

看一下WpfTextViewHost课程;文章解释说这种类型实际上是UIElement,所以我想可以托管它的多个实例......