A.R*_*.R. 36 c# visual-studio-2010 visual-studio visual-studio-extensions
我正在尝试开始使用Visual Studio(2010)扩展,我很难找到合适的材料.我有SDK,但包含的样本似乎是装饰,窗口和图标.
我正在尝试创建一个可以直接使用文本编辑器的扩展(以字母方式对类中的所有方法名称进行字母顺序排列,或者将所有常量名称设置为大写),但我找不到此类功能的演示,甚至是教程.
有谁知道我在哪里可以找到这种东西?
Ray*_*Ray 57
我有完全相同的问题,现在已经浏览了几个小时,直到我能够理解并解释你如何开始这样的扩展.
在我的下面的示例中,我们将创建一个小而简单的扩展,在编辑完成后,它总是将"Hello"添加到代码文件的开头.这是非常基本的,但应该让你知道如何继续开发这个东西.
警告:您必须完全自己解析代码文件 - Visual Studio不会向您提供有关类,方法或其他内容以及它们包含的内容的任何信息.这是执行代码格式化工具时要采取的最大障碍,并且不会在此答案中介绍.[*]
对于那些跳过此答案的人,请确保先下载并安装Visual Studio SDK,否则您将找不到第一步中提到的项目类型.
创建项目
首先创建一个"Visual C#> Extensibility> VSIX Project"类型的新项目(仅当您选择.NET Framework 4作为目标框架时才可见).请注意,您可能必须选择"编辑器分类器"项目类型而不是"VSIX项目"类型才能使其正常工作.评论如下.
创建项目后,将打开"source.extension.vsixmanifest"文件,使您能够设置产品名称,作者,版本,描述,图标等.我认为这一步非常自我解释,您现在可以关闭选项卡,稍后通过打开vsixmanifest文件来恢复它.
创建一个监听器类以获得有关文本编辑器实例创建的通知
接下来,每当在Visual Studio中创建文本编辑器并将我们的代码格式化工具绑定到它时,我们都需要监听.VS2010中的文本编辑器是一个实例IWpfTextView.
在项目中添加一个新类并命名TextViewCreationListener.该类必须实现该Microsoft.VisualStudio.Text.Editor.IWpfTextViewCreationListener接口.您需要将Microsoft.VisualStudio.Text.UI.Wpf的引用添加到项目中.可以在VisualStudioIntegration\Common\Assemblies\v4.0下的Visual Studio SDK目录中找到程序集DLL .
您必须实现TextViewCreated接口的方法.此方法有一个参数,指定已创建的文本编辑器的实例.我们将创建一个新的代码格式化类,稍后将该实例传递给该类.
我们需要TextViewCreationListener通过指定属性使Visual Studio可见[Export(typeof(IWpfTextViewCreationListener))].将System.ComponentModel.Composition的引用添加到Export属性的项目中.
此外,我们需要指定代码格式化程序应绑定到文本编辑器的文件类型.我们只想格式化代码文件而不是纯文本文件,因此我们将该属性添加[ContentType("code")]到监听器类.您必须为此项目添加对Microsoft.VisualStudio.CoreUtility的引用.
此外,我们只想更改可编辑的代码而不是它周围的颜色或装饰(如示例项目中所示),因此我们将该属性添加[TextViewRole(PredefinedTextViewRoles.Editable)]到类中.再次,您需要一个新的引用,这次是Microsoft.VisualStudio.Text.UI.
将该类标记为内部密封.至少这是我的建议.现在你的类看起来应该类似于:
[ContentType("code")]
[Export(typeof(IWpfTextViewCreationListener))]
[TextViewRole(PredefinedTextViewRoles.Editable)]
internal sealed class TextViewCreationListener : IWpfTextViewCreationListener
{
public void TextViewCreated(IWpfTextView textView)
{
}
}
Run Code Online (Sandbox Code Playgroud)创建用于代码格式化的类
接下来,我们需要一个处理代码格式化逻辑,排序方法等的类.同样,在这个例子中,只要编辑完成,它就会在文件的开头添加"Hello".
添加一个名为Formatter项目的新类.
添加一个带有一个IWpfTextView参数的构造函数.请记住,我们想要在TextViewCreated我们的侦听器类的方法中将创建的编辑器实例传递给此格式化类(只需添加new Formatter(textView);到那里的方法).
将传递的实例保存在成员变量中.在稍后格式化代码时(例如,用于检索插入位置),它将变得很方便.还要绑定编辑器实例的属性Changed和PostChanged事件TextBuffer:
public Formatter(IWpfTextView view)
{
_view = view;
_view.TextBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(TextBuffer_Changed);
_view.TextBuffer.PostChanged += new EventHandler(TextBuffer_PostChanged);
}
Run Code Online (Sandbox Code Playgroud)Changed每次编辑时都会调用该事件(例如,键入字符,粘贴代码或编程更改).因为它也会对程序化更改做出反应,所以我使用bool来确定我们的扩展或用户/其他任何内容是否正在更改代码,并且FormatCode()只有在我们的扩展尚未编辑时才调用我的自定义方法.否则,您将递归调用此方法,这将导致Visual Studio崩溃:
private void TextBuffer_Changed(object sender, TextContentChangedEventArgs e)
{
if (!_isChangingText)
{
_isChangingText = true;
FormatCode(e);
}
}
Run Code Online (Sandbox Code Playgroud)我们必须PostChanged再次在事件处理程序中重置此bool成员变量false.
让我们将事件的事件参数传递Changed给我们的自定义FormatCode方法,因为它们包含上次编辑和现在之间已更改的内容.这些编辑存储在e.Changes类型的数组中INormalizedTextChangeCollection(s.我帖子末尾的链接,以获取有关此类型的更多信息).我们遍历所有这些编辑,并HandleChange使用此编辑生成的新文本调用我们的自定义方法.
private void FormatCode(TextContentChangedEventArgs e)
{
if (e.Changes != null)
{
for (int i = 0; i < e.Changes.Count; i++)
{
HandleChange(e.Changes[0].NewText);
}
}
}
Run Code Online (Sandbox Code Playgroud)在该HandleChange方法中,我们实际上可以扫描关键字以便以特定方式处理这些关键字(请记住,您必须自己解析任何代码!) - 但是在这里我们只是笨拙地将"Hello"添加到文件的开头以进行测试.例如,我们必须更改TextBuffer编辑器实例.为此,我们需要创建一个ITextEdit对象,我们可以使用该对象操作文本并在之后应用它的更改.代码非常自我解释:
private void HandleChange(string newText)
{
ITextEdit edit = _view.TextBuffer.CreateEdit();
edit.Insert(0, "Hello");
edit.Apply();
}
Run Code Online (Sandbox Code Playgroud)编译此加载项时,Visual Studio的实验配置单元启动时只加载了我们的扩展.创建一个新的C#文件并开始输入以查看结果.
我希望这能为您提供一些如何继续本主题的想法.我现在必须自己去探索它.
我强烈推荐MSDN上编辑器的文本模型的文档,以获得有关如何执行此操作的提示. http://msdn.microsoft.com/en-us/library/dd885240.aspx#textmodel
脚注
[*]请注意,Visual Studio 2015或更新版本附带Rosyln编译器平台,它确实已经为您分析了C#和VB.NET文件(也可能是其他预安装的语言)并暴露了它们的层次结构语法结构,但我是不是这个主题的专家还没有给出如何使用这些新服务的答案.无论如何,启动编辑器扩展的基本进度与本答案中描述的相同.请注意 - 如果您使用这些服务 - 您将依赖于Visual Studio 2015+,并且该扩展将无法在早期版本中使用.