签名帮助 (也称为 参数信息) 显示一个方法的签名在工具提示中,当用户类型参数列表启动字符时 (通常为左括号)。 当参数和参数分隔符 (通常为英文逗号) 类型化,以粗体更新工具提示显示下一个参数。 可以定义签名帮助在语言服务中,也可以定义拥有文件扩展名与内容类型并显示该类型的签名帮助,也可以显示现有内容类型的签名帮助 (例如, “文本”)。 本演练演示了如何显示 “文本”内容类型的签名帮助。
,例如,签名帮助通过键入特定字符通常触发 “(" (左括号),例如,和关闭通过键入另一字符 ")” (结束括号)。 通过键入字符触发的 IntelliSense 功能可以实现使用击键 ( IOleCommandTarget 界面) 和实现 IVsTextViewCreationListener 接口的处理程序提供程序的命令处理程序。 若要创建签名帮助源,是签名列表参与签名帮助,实现 ISignatureHelpSource 接口和实现 ISignatureHelpSourceProvider 接口的数据源提供程序。 提供程序是托管扩展性框架 (MEF)组成部分,并对导出源和控制器类和导入服务和代理,例如, ITextStructureNavigatorSelectorService,在文本缓冲区可以导航和 ISignatureHelpBroker,负责触发签名帮助会话。
本演练演示如何实现硬编码的签名帮助设置标识符。 在完整的实现,语言对提供该内容负责。
系统必备
若要完成本演练,您必须安装 Visual Studio 2010 SDK。
备注
有关 Visual Studio SDK 的更多信息,请参见 扩展 Visual Studio 概述。若要查找有关中所列如何下载 Visual Studio SDK,请 Visual Studio Extensibility Developer Center 参见 MSDN 网站上。
创建 MEF 项目
创建 MEF 项目
创建一个编辑分类器项目。 将解决方案命名为 SignatureHelpTest。
打开在 VSIX 清单编辑器中的 Source.extension.vsixmanifest 文件。
确保 Content 归为包含一个 MEF 组件内容类型,而 Path 设置为 SignatureHelpTest.dll。
保存并关闭的 Source.extension.vsixmanifest。
将下列引用添加到项目,并将 CopyLocal 到 false:
Microsoft.VisualStudio.Editor
Microsoft.VisualStudio.Language.Intellisense
Microsoft.VisualStudio.OLE.Interop
Microsoft.VisualStudio.Shell
Microsoft.VisualStudio.TextManager.Interop
删除现有类文件。
实现签名帮助签名和参数
签名帮助源根据实现 ISignature,每个包含参数实现 IParameter的签名。 在完整实现,此信息从语言文档中获取,但是,在此示例中,签名硬编码。
若要实现签名帮助签名和参数
将类文件并将其命名为 SignatureHelpSource。
添加下面的导入。
Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Text Imports System.Collections.ObjectModel Imports System.ComponentModel.Composition Imports System.Runtime.InteropServices Imports Microsoft.VisualStudio.Language.Intellisense Imports Microsoft.VisualStudio.Text Imports Microsoft.VisualStudio.Text.Editor Imports Microsoft.VisualStudio.Utilities Imports Microsoft.VisualStudio.Editor Imports Microsoft.VisualStudio.Text.Operations Imports Microsoft.VisualStudio Imports Microsoft.VisualStudio.TextManager.Interop Imports Microsoft.VisualStudio.OLE.Interop
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel.Composition; using System.Runtime.InteropServices; using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Utilities; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio; using Microsoft.VisualStudio.TextManager.Interop; using Microsoft.VisualStudio.OLE.Interop;
添加类被命名为该 TestParameter 实现 IParameter。
Friend Class TestParameter Implements IParameter
internal class TestParameter : IParameter
添加将所有特性的构造函数。
Public Sub New(ByVal documentation As String, ByVal locus As Span, ByVal name As String, ByVal signature As ISignature) Me.privateDocumentation = documentation Me.privateLocus = locus Me.privateName = name Me.privateSignature = signature End Sub
public TestParameter(string documentation, Span locus, string name, ISignature signature) { Documentation = documentation; Locus = locus; Name = name; Signature = signature; }
添加 IParameter属性。
Private privateDocumentation As String ReadOnly Property Documentation() As String Implements IParameter.Documentation Get Return privateDocumentation End Get End Property Private privateLocus As Span ReadOnly Property Locus() As Span Implements IParameter.Locus Get Return privateLocus End Get End Property Private privateName As String ReadOnly Property Name() As String Implements IParameter.Name Get Return privateName End Get End Property Private privateSignature As ISignature ReadOnly Property Signature() As ISignature Implements IParameter.Signature Get Return privateSignature End Get End Property Private privatePrettyPrintedLocus As Span ReadOnly Property PrettyPrintedLocus() As Span Implements IParameter.PrettyPrintedLocus Get Return privatePrettyPrintedLocus End Get End Property
public string Documentation { get; private set; } public Span Locus { get; private set; } public string Name { get; private set; } public ISignature Signature { get; private set; } public Span PrettyPrintedLocus { get; private set; }
添加类被命名为该 TestSignature 实现 ISignature。
Friend Class TestSignature Implements ISignature
internal class TestSignature : ISignature
添加某些私有字段。
Private m_subjectBuffer As ITextBuffer Private m_currentParameter As IParameter Private m_content As String Private m_documentation As String Friend m_applicableToSpan As ITrackingSpan Friend m_parameters As ReadOnlyCollection(Of IParameter) Private m_printContent As String
private ITextBuffer m_subjectBuffer; private IParameter m_currentParameter; private string m_content; private string m_documentation; private ITrackingSpan m_applicableToSpan; private ReadOnlyCollection<IParameter> m_parameters; private string m_printContent;
将设置添加字段并订阅 Changed 事件的构造函数。
Friend Sub New(ByVal subjectBuffer As ITextBuffer, ByVal content As String, ByVal doc As String, ByVal parameters As ReadOnlyCollection(Of IParameter)) m_subjectBuffer = subjectBuffer m_content = content m_documentation = doc m_parameters = parameters AddHandler m_subjectBuffer.Changed, AddressOf OnSubjectBufferChanged End Sub
internal TestSignature(ITextBuffer subjectBuffer, string content, string doc, ReadOnlyCollection<IParameter> parameters) { m_subjectBuffer = subjectBuffer; m_content = content; m_documentation = doc; m_parameters = parameters; m_subjectBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(OnSubjectBufferChanged); }
声明 CurrentParameterChanged 事件。 ,当用户填充一个在签名时,的参数将引发此事件。
Public Event CurrentParameterChanged As EventHandler(Of CurrentParameterChangedEventArgs) Implements ISignature.CurrentParameterChanged
public event EventHandler<CurrentParameterChangedEventArgs> CurrentParameterChanged;
实现 CurrentParameter 属性,使其 CurrentParameterChanged 引发事件,更改时属性值。
ReadOnly Property CurrentParameter() As IParameter Implements ISignature.CurrentParameter Get Return m_currentParameter End Get End Property
public IParameter CurrentParameter { get { return m_currentParameter; } internal set { if (m_currentParameter != value) { IParameter prevCurrentParameter = m_currentParameter; m_currentParameter = value; this.RaiseCurrentParameterChanged(prevCurrentParameter, m_currentParameter); } } }
添加 CurrentParameterChanged 引发事件的方法。
Private Sub RaiseCurrentParameterChanged(ByVal prevCurrentParameter As IParameter, ByVal newCurrentParameter As IParameter) Dim tempHandler As EventHandler(Of CurrentParameterChangedEventArgs) = Me.CurrentParameterChangedEvent If tempHandler IsNot Nothing Then tempHandler(Me, New CurrentParameterChangedEventArgs(prevCurrentParameter, newCurrentParameter)) End If End Sub
private void RaiseCurrentParameterChanged(IParameter prevCurrentParameter, IParameter newCurrentParameter) { EventHandler<CurrentParameterChangedEventArgs> tempHandler = this.CurrentParameterChanged; if (tempHandler != null) { tempHandler(this, new CurrentParameterChangedEventArgs(prevCurrentParameter, newCurrentParameter)); } }
添加通过比较逗号分隔的计算当前参数。 ApplicableToSpan 的用逗号数在签名的方法。
Friend Sub ComputeCurrentParameter() If Parameters.Count = 0 Then Me.m_currentParameter = Nothing Return End If 'the number of commas in the string is the index of the current parameter Dim sigText As String = ApplicableToSpan.GetText(m_subjectBuffer.CurrentSnapshot) Dim currentIndex As Integer = 0 Dim commaCount As Integer = 0 Do While currentIndex < sigText.Length Dim commaIndex As Integer = sigText.IndexOf(","c, currentIndex) If commaIndex = -1 Then Exit Do End If commaCount += 1 currentIndex = commaIndex + 1 Loop If commaCount < Parameters.Count Then Me.m_currentParameter = Parameters(commaCount) Else 'too many commas, so use the last parameter as the current one. Me.m_currentParameter = Parameters(Parameters.Count - 1) End If End Sub
internal void ComputeCurrentParameter() { if (Parameters.Count == 0) { this.CurrentParameter = null; return; } //the number of commas in the string is the index of the current parameter string sigText = ApplicableToSpan.GetText(m_subjectBuffer.CurrentSnapshot); int currentIndex = 0; int commaCount = 0; while (currentIndex < sigText.Length) { int commaIndex = sigText.IndexOf(',', currentIndex); if (commaIndex == -1) { break; } commaCount++; currentIndex = commaIndex + 1; } if (commaCount < Parameters.Count) { this.CurrentParameter = Parameters[commaCount]; } else { //too many commas, so use the last parameter as the current one. this.CurrentParameter = Parameters[Parameters.Count - 1]; } }
添加调用 ComputeCurrentParameter() 方法的 Changed 事件的事件处理程序。
Friend Sub OnSubjectBufferChanged(ByVal sender As Object, ByVal e As TextContentChangedEventArgs) Me.ComputeCurrentParameter() End Sub
internal void OnSubjectBufferChanged(object sender, TextContentChangedEventArgs e) { this.ComputeCurrentParameter(); }
实现 ApplicableToSpan 属性。 对应于文本范围。缓冲区 (签名的应用此属性包含 ITrackingSpan 。
ReadOnly Property ApplicableToSpan() As ITrackingSpan Implements ISignature.ApplicableToSpan Get Return (m_applicableToSpan) End Get End Property
public ITrackingSpan ApplicableToSpan { get { return (m_applicableToSpan); } internal set { m_applicableToSpan = value; } }
实现其他参数。
ReadOnly Property Content() As String Implements ISignature.Content Get Return (m_content) End Get End Property ReadOnly Property Documentation() As String Implements ISignature.Documentation Get Return (m_documentation) End Get End Property ReadOnly Property Parameters() As ReadOnlyCollection(Of IParameter) Implements ISignature.Parameters Get Return (m_parameters) End Get End Property ReadOnly Property PrettyPrintedContent() As String Implements ISignature.PrettyPrintedContent Get Return (m_printContent) End Get End Property
public string Content { get { return (m_content); } internal set { m_content = value; } } public string Documentation { get { return (m_documentation); } internal set { m_documentation = value; } } public ReadOnlyCollection<IParameter> Parameters { get { return (m_parameters); } internal set { m_parameters = value; } } public string PrettyPrintedContent { get { return (m_printContent); } internal set { m_printContent = value; } }
实现签名帮助源
签名帮助源是您提供信息的一组签名。
实现签名帮助源
添加类被命名为该 TestSignatureHelpSource 实现 ISignatureHelpSource。
Friend Class TestSignatureHelpSource Implements ISignatureHelpSource
internal class TestSignatureHelpSource : ISignatureHelpSource
添加对文本缓冲区。
Private m_textBuffer As ITextBuffer
private ITextBuffer m_textBuffer;
添加用于设置文本缓冲区和签名帮助提供程序源的构造函数。
Public Sub New(ByVal textBuffer As ITextBuffer) m_textBuffer = textBuffer End Sub
public TestSignatureHelpSource(ITextBuffer textBuffer) { m_textBuffer = textBuffer; }
实现 AugmentSignatureHelpSession 方法。 在此示例中,签名硬编码,但是,在完整实现可以从获取语言文档的此信息。
Public Sub AugmentSignatureHelpSession(ByVal session As ISignatureHelpSession, ByVal signatures As IList(Of ISignature)) Implements ISignatureHelpSource.AugmentSignatureHelpSession Dim snapshot As ITextSnapshot = m_textBuffer.CurrentSnapshot Dim position As Integer = session.GetTriggerPoint(m_textBuffer).GetPosition(snapshot) Dim applicableToSpan As ITrackingSpan = m_textBuffer.CurrentSnapshot.CreateTrackingSpan(New Span(position, 0), SpanTrackingMode.EdgeInclusive, 0) signatures.Add(CreateSignature(m_textBuffer, "add(int firstInt, int secondInt)", "Documentation for adding integers.", applicableToSpan)) signatures.Add(CreateSignature(m_textBuffer, "add(double firstDouble, double secondDouble)", "Documentation for adding doubles.", applicableToSpan)) End Sub
public void AugmentSignatureHelpSession(ISignatureHelpSession session, IList<ISignature> signatures) { ITextSnapshot snapshot = m_textBuffer.CurrentSnapshot; int position = session.GetTriggerPoint(m_textBuffer).GetPosition(snapshot); ITrackingSpan applicableToSpan = m_textBuffer.CurrentSnapshot.CreateTrackingSpan( new Span(position, 0), SpanTrackingMode.EdgeInclusive, 0); signatures.Add(CreateSignature(m_textBuffer, "add(int firstInt, int secondInt)", "Documentation for adding integers.", applicableToSpan)); signatures.Add(CreateSignature(m_textBuffer, "add(double firstDouble, double secondDouble)", "Documentation for adding doubles.", applicableToSpan)); }
帮助器方法 CreateSignature() 为图提供。
Private Function CreateSignature(ByVal textBuffer As ITextBuffer, ByVal methodSig As String, ByVal methodDoc As String, ByVal span As ITrackingSpan) As TestSignature Dim sig As New TestSignature(textBuffer, methodSig, methodDoc, Nothing) AddHandler textBuffer.Changed, AddressOf sig.OnSubjectBufferChanged 'find the parameters in the method signature (expect methodname(one, two) Dim pars() As String = methodSig.Split(New Char() {"("c, ","c, ")"c}) Dim paramList As New List(Of IParameter)() Dim locusSearchStart As Integer = 0 For i As Integer = 1 To pars.Length - 1 Dim param As String = pars(i).Trim() If String.IsNullOrEmpty(param) Then Continue For End If 'find where this parameter is located in the method signature Dim locusStart As Integer = methodSig.IndexOf(param, locusSearchStart) If locusStart >= 0 Then Dim locus As New Span(locusStart, param.Length) locusSearchStart = locusStart + param.Length paramList.Add(New TestParameter("Documentation for the parameter.", locus, param, sig)) End If Next i sig.m_Parameters = New ReadOnlyCollection(Of IParameter)(paramList) sig.m_ApplicableToSpan = span sig.ComputeCurrentParameter() Return sig End Function
private TestSignature CreateSignature(ITextBuffer textBuffer, string methodSig, string methodDoc, ITrackingSpan span) { TestSignature sig = new TestSignature(textBuffer, methodSig, methodDoc, null); textBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(sig.OnSubjectBufferChanged); //find the parameters in the method signature (expect methodname(one, two) string[] pars = methodSig.Split(new char[] { '(', ',', ')' }); List<IParameter> paramList = new List<IParameter>(); int locusSearchStart = 0; for (int i = 1; i < pars.Length; i++) { string param = pars[i].Trim(); if (string.IsNullOrEmpty(param)) continue; //find where this parameter is located in the method signature int locusStart = methodSig.IndexOf(param, locusSearchStart); if (locusStart >= 0) { Span locus = new Span(locusStart, param.Length); locusSearchStart = locusStart + param.Length; paramList.Add(new TestParameter("Documentation for the parameter.", locus, param, sig)); } } sig.Parameters = new ReadOnlyCollection<IParameter>(paramList); sig.ApplicableToSpan = span; sig.ComputeCurrentParameter(); return sig; }
实现 GetBestMatch 方法。 在此示例中,有两个签名,每个具有两个参数。 因此,不需要使用此方法。 在一个更全面的实现,多个签名帮助源可用,此方法用于确定最高优先级的签名帮助数据源是否可提供了匹配的签名。 如果不能,则该方法返回 null,并 NeXT 高优先级源请求提供匹配。
Public Function GetBestMatch(ByVal session As ISignatureHelpSession) As ISignature Implements ISignatureHelpSource.GetBestMatch If session.Signatures.Count > 0 Then Dim applicableToSpan As ITrackingSpan = session.Signatures(0).ApplicableToSpan Dim text As String = applicableToSpan.GetText(applicableToSpan.TextBuffer.CurrentSnapshot) If text.Trim().Equals("add") Then 'get only "add" Return session.Signatures(0) End If End If Return Nothing End Function
public ISignature GetBestMatch(ISignatureHelpSession session) { if (session.Signatures.Count > 0) { ITrackingSpan applicableToSpan = session.Signatures[0].ApplicableToSpan; string text = applicableToSpan.GetText(applicableToSpan.TextBuffer.CurrentSnapshot); if (text.Trim().Equals("add")) //get only "add" return session.Signatures[0]; } return null; }
执行 Dispose() 方法:
Private m_isDisposed As Boolean Public Sub Dispose() Implements IDisposable.Dispose If Not m_isDisposed Then GC.SuppressFinalize(Me) m_isDisposed = True End If End Sub
private bool m_isDisposed; public void Dispose() { if (!m_isDisposed) { GC.SuppressFinalize(this); m_isDisposed = true; } }
实现签名帮助提供程序源
签名帮助源提供程序负责导出 managed extensibility framework 组件部件 (MEF)和在运行时实例化签名帮助源。
实现签名帮助提供程序源
添加实现 ISignatureHelpSourceProvider名为 TestSignatureHelpSourceProvider 的类,并将其导出与 NameAttribute, “text” ContentTypeAttribute 和 OrderAttribute Before= " default”。
<Export(GetType(ISignatureHelpSourceProvider)), Name("Signature Help source"), Order(Before:="default"), ContentType("text")> Friend Class TestSignatureHelpSourceProvider Implements ISignatureHelpSourceProvider
[Export(typeof(ISignatureHelpSourceProvider))] [Name("Signature Help source")] [Order(Before = "default")] [ContentType("text")] internal class TestSignatureHelpSourceProvider : ISignatureHelpSourceProvider
通过实例化 TestSignatureHelpSource实现 TryCreateSignatureHelpSource 。
Public Function TryCreateSignatureHelpSource(ByVal textBuffer As ITextBuffer) As ISignatureHelpSource Implements ISignatureHelpSourceProvider.TryCreateSignatureHelpSource Return New TestSignatureHelpSource(textBuffer) End Function
public ISignatureHelpSource TryCreateSignatureHelpSource(ITextBuffer textBuffer) { return new TestSignatureHelpSource(textBuffer); }
实现命令处理程序
签名帮助由通常触发 (字符和关闭由) 字符。 通过实现 IOleCommandTarget 可以处理这些击键,使其触发签名帮助会话,在收到时 (已知的方法名称后面的字符,和关闭会话,在收到) 字符时。
实现命令处理程序
添加类被命名为该 TestSignatureHelpCommand 实现 IOleCommandTarget。
Friend NotInheritable Class TestSignatureHelpCommandHandler Implements IOleCommandTarget
internal sealed class TestSignatureHelpCommandHandler : IOleCommandTarget
添加私有字段可以添加命令处理程序。指挥系统处理程序) 的 IVsTextView 适配器 (,文本视图、签名帮助代理和会话、 ITextStructureNavigator和下 IOleCommandTarget。
Private m_nextCommandHandler As IOleCommandTarget Private m_textView As ITextView Private m_broker As ISignatureHelpBroker Private m_session As ISignatureHelpSession Private m_navigator As ITextStructureNavigator
IOleCommandTarget m_nextCommandHandler; ITextView m_textView; ISignatureHelpBroker m_broker; ISignatureHelpSession m_session; ITextStructureNavigator m_navigator;
添加一个构造函数初始化这些字段并添加命令筛选器。指挥系统筛选器。
Friend Sub New(ByVal textViewAdapter As IVsTextView, ByVal textView As ITextView, ByVal nav As ITextStructureNavigator, ByVal broker As ISignatureHelpBroker) Me.m_textView = textView Me.m_broker = broker Me.m_navigator = nav 'add this to the filter chain textViewAdapter.AddCommandFilter(Me, m_nextCommandHandler) End Sub
internal TestSignatureHelpCommandHandler(IVsTextView textViewAdapter, ITextView textView, ITextStructureNavigator nav, ISignatureHelpBroker broker) { this.m_textView = textView; this.m_broker = broker; this.m_navigator = nav; //add this to the filter chain textViewAdapter.AddCommandFilter(this, out m_nextCommandHandler); }
请执行 Exec 方法触发签名帮助会话,当命令筛选器接收时 (在之一的字符已知的方法名称之后和关闭会话,在收到) 字符时,该会话处于活动状态时。 每次,转发命令。
Public Function Exec(ByRef pguidCmdGroup As Guid, ByVal nCmdID As UInteger, ByVal nCmdexecopt As UInteger, ByVal pvaIn As IntPtr, ByVal pvaOut As IntPtr) As Integer Implements IOleCommandTarget.Exec Dim typedChar As Char = Char.MinValue If pguidCmdGroup = VSConstants.VSStd2K AndAlso nCmdID = CUInt(VSConstants.VSStd2KCmdID.TYPECHAR) Then typedChar = CChar(ChrW(CUShort(Marshal.GetObjectForNativeVariant(pvaIn)))) If typedChar.Equals("("c) Then 'move the point back so it's in the preceding word Dim point As SnapshotPoint = m_textView.Caret.Position.BufferPosition - 1 Dim extent As TextExtent = m_navigator.GetExtentOfWord(point) Dim word As String = extent.Span.GetText() If word.Equals("add") Then m_session = m_broker.TriggerSignatureHelp(m_textView) End If ElseIf typedChar.Equals(")"c) AndAlso m_session IsNot Nothing Then m_session.Dismiss() m_session = Nothing End If End If Return m_nextCommandHandler.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut) End Function
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { char typedChar = char.MinValue; if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); if (typedChar.Equals('(')) { //move the point back so it's in the preceding word SnapshotPoint point = m_textView.Caret.Position.BufferPosition - 1; TextExtent extent = m_navigator.GetExtentOfWord(point); string word = extent.Span.GetText(); if (word.Equals("add")) m_session = m_broker.TriggerSignatureHelp(m_textView); } else if (typedChar.Equals(')') && m_session != null) { m_session.Dismiss(); m_session = null; } } return m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); }
执行 QueryStatus 方法,以便始终向前命令。
Public Function QueryStatus(ByRef pguidCmdGroup As Guid, ByVal cCmds As UInteger, ByVal prgCmds() As OLECMD, ByVal pCmdText As IntPtr) As Integer Implements IOleCommandTarget.QueryStatus Return m_nextCommandHandler.QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText) End Function
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) { return m_nextCommandHandler.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText); }
实现签名帮助提供程序命令
通过实现 IVsTextViewCreationListener 实例化命令处理程序的签名帮助命令,在创建文本视图时。
实现签名帮助提供程序命令
添加实现 IVsTextViewCreationListener 名为 TestSignatureHelpController 的类并将其导出与 NameAttribute、 ContentTypeAttribute和 TextViewRoleAttribute。
<Export(GetType(IVsTextViewCreationListener)), Name("Signature Help controller"), TextViewRole(PredefinedTextViewRoles.Editable), ContentType("text")> Friend Class TestSignatureHelpCommandProvider Implements IVsTextViewCreationListener
[Export(typeof(IVsTextViewCreationListener))] [Name("Signature Help controller")] [TextViewRole(PredefinedTextViewRoles.Editable)] [ContentType("text")] internal class TestSignatureHelpCommandProvider : IVsTextViewCreationListener
导入 IVsEditorAdaptersFactoryService (用于获取 ITextView命名 IVsTextView 对象), ITextStructureNavigatorSelectorService (用于查找当前单词) 和 ISignatureHelpBroker (触发签名帮助会话)。
<Import()> Friend AdapterService As IVsEditorAdaptersFactoryService <Import()> Friend Property NavigatorService() As ITextStructureNavigatorSelectorService <Import()> Friend SignatureHelpBroker As ISignatureHelpBroker
[Import] internal IVsEditorAdaptersFactoryService AdapterService; [Import] internal ITextStructureNavigatorSelectorService NavigatorService { get; set; } [Import] internal ISignatureHelpBroker SignatureHelpBroker;
通过实例化 TestSignatureCommandHandler执行 VsTextViewCreated 方法。
Public Sub VsTextViewCreated(ByVal textViewAdapter As IVsTextView) Implements IVsTextViewCreationListener.VsTextViewCreated Dim textView As ITextView = AdapterService.GetWpfTextView(textViewAdapter) If textView Is Nothing Then Return End If textView.Properties.GetOrCreateSingletonProperty(Function() New TestSignatureHelpCommandHandler(textViewAdapter, textView, NavigatorService.GetTextStructureNavigator(textView.TextBuffer), SignatureHelpBroker)) End Sub
public void VsTextViewCreated(IVsTextView textViewAdapter) { ITextView textView = AdapterService.GetWpfTextView(textViewAdapter); if (textView == null) return; textView.Properties.GetOrCreateSingletonProperty( () => new TestSignatureHelpCommandHandler(textViewAdapter, textView, NavigatorService.GetTextStructureNavigator(textView.TextBuffer), SignatureHelpBroker)); }
生成并测试代码
若要测试此代码,请生成 SignatureHelpTest 解决方案并运行在的实验实例。
生成和测试 SignatureHelpTest 解决方案
生成解决方案。
当您运行在调试器中查看此项目, Visual Studio 的第二个实例进行实例化。
创建一个文本文件并键入包含单词 “添加”以及左括号的某些文本。
在键入左括号后,您应看到显示两个签名列表 add() 方法的工具提示。