当用户键入参数列表起始字符(通常是左括号)时,签名帮助(也称为 参数信息)在工具提示中显示方法的签名。 作为参数和参数分隔符(通常为逗号),工具提示将更新为以粗体显示下一个参数。 可以通过以下方式定义签名帮助:在语言服务的上下文中,定义自己的文件扩展名和内容类型,并仅显示该类型的签名帮助,或显示现有内容类型的签名帮助(例如“text”)。 本演练演示如何显示“text”内容类型的签名帮助。
签名帮助通常通过键入特定字符(例如“(”)(左括号)触发,并通过键入另一个字符(例如“)”(右括号)来消除。 可以通过使用键击( IOleCommandTarget 接口)的命令处理程序和实现 IVsTextViewCreationListener 接口的处理程序提供程序来实现通过键入字符触发的 IntelliSense 功能。 若要创建签名帮助源,该源是参与签名帮助的签名列表,请实现 ISignatureHelpSource 该接口和运行接口的 ISignatureHelpSourceProvider 源提供程序。 提供程序是托管扩展性框架(MEF)组件部件,负责导出源和控制器类以及导入服务和中转站,例如 ITextStructureNavigatorSelectorService,允许在文本缓冲区中导航,以及 ISignatureHelpBroker触发签名帮助会话的提供程序。
本演练演示如何为硬编码的标识符集设置签名帮助。 在完整的实现中,语言负责提供该内容。
创建 MEF 项目
创建 MEF 项目
创建 C# VSIX 项目。 (在 “新建项目 ”对话框,选择 Visual C# /扩展性,然后选择 VSIX Project。)将解决方案 SignatureHelpTest
命名为 。
向项目添加编辑器分类器项模板。 有关详细信息,请参阅使用编辑器项模板创建扩展。
删除现有的类文件。
将以下引用添加到项目,并确保 CopyLocal 设置为 false
:
Microsoft.VisualStudio.Editor
Microsoft.VisualStudio.Language.Intellisense
Microsoft.VisualStudio.OLE.Interop
Microsoft.VisualStudio.Shell.14.0
Microsoft.VisualStudio.TextManager.Interop
实现签名帮助签名和参数
签名帮助源基于实现 ISignature的签名,每个签名都包含实现 IParameter的参数。 在完整实现中,此信息将从语言文档获取,但在此示例中,签名是硬编码的。
实现签名帮助签名和参数
添加一个类文件并将其命名为 SignatureHelpSource
。
添加以下 import 语句。
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;
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
添加一个名为 TestParameter
实现的 IParameter类。
internal class TestParameter : IParameter
Friend Class TestParameter
Implements IParameter
添加设置所有属性的构造函数。
public TestParameter(string documentation, Span locus, string name, ISignature signature)
{
Documentation = documentation;
Locus = locus;
Name = name;
Signature = signature;
}
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
添加 . IParameter的属性
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; }
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
添加一个名为 TestSignature
实现的 ISignature类。
internal class TestSignature : ISignature
Friend Class TestSignature
Implements ISignature
添加一些专用字段。
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;
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
添加一个构造函数,用于设置字段并订阅事件 Changed 。
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);
}
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
声明事件 CurrentParameterChanged
。 当用户填写签名中的某个参数时,将引发此事件。
public event EventHandler<CurrentParameterChangedEventArgs> CurrentParameterChanged;
Public Event CurrentParameterChanged As EventHandler(Of CurrentParameterChangedEventArgs) Implements ISignature.CurrentParameterChanged
实现该 CurrentParameter 属性,以便在属性值发生更改时引发 CurrentParameterChanged
事件。
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);
}
}
}
ReadOnly Property CurrentParameter() As IParameter Implements ISignature.CurrentParameter
Get
Return m_currentParameter
End Get
End Property
添加引发 CurrentParameterChanged
事件的方法。
private void RaiseCurrentParameterChanged(IParameter prevCurrentParameter, IParameter newCurrentParameter)
{
EventHandler<CurrentParameterChangedEventArgs> tempHandler = this.CurrentParameterChanged;
if (tempHandler != null)
{
tempHandler(this, new CurrentParameterChangedEventArgs(prevCurrentParameter, newCurrentParameter));
}
}
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
添加一个方法,该方法通过将签名中的 ApplicableToSpan 逗号数与签名中的逗号数进行比较来计算当前参数。
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];
}
}
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
为 Changed 调用 ComputeCurrentParameter()
该方法的事件添加事件处理程序。
internal void OnSubjectBufferChanged(object sender, TextContentChangedEventArgs e)
{
this.ComputeCurrentParameter();
}
Friend Sub OnSubjectBufferChanged(ByVal sender As Object, ByVal e As TextContentChangedEventArgs)
Me.ComputeCurrentParameter()
End Sub
实现 ApplicableToSpan 属性。 此属性包含与 ITrackingSpan 签名应用到的缓冲区中的文本范围对应的属性。
public ITrackingSpan ApplicableToSpan
{
get { return (m_applicableToSpan); }
internal set { m_applicableToSpan = value; }
}
ReadOnly Property ApplicableToSpan() As ITrackingSpan Implements ISignature.ApplicableToSpan
Get
Return (m_applicableToSpan)
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; }
}
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
实现签名帮助源
签名帮助源是你为其提供信息的签名集。
实现签名帮助源
添加一个名为 TestSignatureHelpSource
实现的 ISignatureHelpSource类。
internal class TestSignatureHelpSource : ISignatureHelpSource
Friend Class TestSignatureHelpSource
Implements ISignatureHelpSource
添加对文本缓冲区的引用。
private ITextBuffer m_textBuffer;
Private m_textBuffer As ITextBuffer
添加设置文本缓冲区和签名帮助源提供程序的构造函数。
public TestSignatureHelpSource(ITextBuffer textBuffer)
{
m_textBuffer = textBuffer;
}
Public Sub New(ByVal textBuffer As ITextBuffer)
m_textBuffer = textBuffer
End Sub
实现 AugmentSignatureHelpSession 方法。 在此示例中,签名是硬编码的,但在完整实现中,你将从语言文档获取此信息。
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));
}
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
仅为了说明提供帮助程序方法 CreateSignature()
。
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;
}
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
实现 GetBestMatch 方法。 在此示例中,只有两个签名,每个签名都有两个参数。 因此,不需要此方法。 在提供多个签名帮助源的更完整的实现中,此方法用于确定最高优先级的签名帮助源是否可以提供匹配的签名。 如果无法,该方法将返回 null,并要求下一个优先级最高的源提供匹配项。
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;
}
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
Dispose()
实现方法:
private bool m_isDisposed;
public void Dispose()
{
if (!m_isDisposed)
{
GC.SuppressFinalize(this);
m_isDisposed = true;
}
}
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
实现签名帮助源提供程序
签名帮助源提供程序负责导出托管扩展性框架 (MEF) 组件部件,以及实例化签名帮助源。
实现签名帮助源提供程序
添加一个名为 TestSignatureHelpSourceProvider
实现 ISignatureHelpSourceProvider的类,并使用“text”和 Before=“default”的 a NameAttribute、一个 ContentTypeAttribute “text”和 a OrderAttribute of Before=“default”导出它。
[Export(typeof(ISignatureHelpSourceProvider))]
[Name("Signature Help source")]
[Order(Before = "default")]
[ContentType("text")]
internal class TestSignatureHelpSourceProvider : ISignatureHelpSourceProvider
<Export(GetType(ISignatureHelpSourceProvider)), Name("Signature Help source"), Order(Before:="default"), ContentType("text")>
Friend Class TestSignatureHelpSourceProvider
Implements ISignatureHelpSourceProvider
TryCreateSignatureHelpSource通过实例化 TestSignatureHelpSource
.
public ISignatureHelpSource TryCreateSignatureHelpSource(ITextBuffer textBuffer)
{
return new TestSignatureHelpSource(textBuffer);
}
Public Function TryCreateSignatureHelpSource(ByVal textBuffer As ITextBuffer) As ISignatureHelpSource Implements ISignatureHelpSourceProvider.TryCreateSignatureHelpSource
Return New TestSignatureHelpSource(textBuffer)
End Function
实现命令处理程序
签名帮助通常由左括号“(”字符触发,右括号“)”字符消除。 你可以通过运行 a IOleCommandTarget 来处理这些击键,以便在它收到以已知方法名称开头的左括号字符时触发签名帮助会话,并在收到右括号字符时关闭会话。
实现命令处理程序
添加一个名为 TestSignatureHelpCommand
实现的 IOleCommandTarget类。
internal sealed class TestSignatureHelpCommandHandler : IOleCommandTarget
Friend NotInheritable Class TestSignatureHelpCommandHandler
Implements IOleCommandTarget
为 IVsTextView 适配器添加专用字段(这使你可以将命令处理程序添加到命令处理程序链)、文本视图、签名帮助代理和会话、a ITextStructureNavigator和下一个 IOleCommandTarget。
IOleCommandTarget m_nextCommandHandler;
ITextView m_textView;
ISignatureHelpBroker m_broker;
ISignatureHelpSession m_session;
ITextStructureNavigator m_navigator;
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
添加构造函数来初始化这些字段,并将命令筛选器添加到命令筛选器链。
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);
}
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
Exec实现当命令筛选器在已知方法名称后收到左括号“(”字符)时触发签名帮助会话的方法,并在会话仍然处于活动状态时接收右括号“)”字符时关闭会话。 在每种情况下,命令都会转发。
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);
}
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
实现该方法 QueryStatus ,使其始终转发命令。
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
{
return m_nextCommandHandler.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
}
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
实现签名帮助命令提供程序
可以通过实现 IVsTextViewCreationListener 创建文本视图时实例化命令处理程序来提供签名帮助命令。
实现签名帮助命令提供程序
使用 和 TextViewRoleAttribute添加一个名为TestSignatureHelpController
实现IVsTextViewCreationListener和导出它的NameAttribute类。 ContentTypeAttribute
[Export(typeof(IVsTextViewCreationListener))]
[Name("Signature Help controller")]
[TextViewRole(PredefinedTextViewRoles.Editable)]
[ContentType("text")]
internal class TestSignatureHelpCommandProvider : IVsTextViewCreationListener
<Export(GetType(IVsTextViewCreationListener)), Name("Signature Help controller"), TextViewRole(PredefinedTextViewRoles.Editable), ContentType("text")>
Friend Class TestSignatureHelpCommandProvider
Implements IVsTextViewCreationListener
IVsEditorAdaptersFactoryService 导入(用于获取ITextView给定IVsTextView对象)、ITextStructureNavigatorSelectorService(用于查找当前单词)和ISignatureHelpBroker(用于触发签名帮助会话)。
[Import]
internal IVsEditorAdaptersFactoryService AdapterService;
[Import]
internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
[Import]
internal ISignatureHelpBroker SignatureHelpBroker;
<Import()>
Friend AdapterService As IVsEditorAdaptersFactoryService
<Import()>
Friend Property NavigatorService() As ITextStructureNavigatorSelectorService
<Import()>
Friend SignatureHelpBroker As ISignatureHelpBroker
VsTextViewCreated通过实例化TestSignatureCommandHandler
方法实现该方法。
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));
}
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
生成并测试代码
若要测试此代码,请生成 SignatureHelpTest 解决方案并在实验实例中运行它。
生成和测试 SignatureHelpTest 解决方案
生成解决方案。
在调试器中运行此项目时,将启动 Visual Studio 的第二个实例。
创建文本文件并键入一些包含单词“add”和左括号的文本。
键入左括号后,应会看到一个工具提示,其中显示该方法的两个签名 add()
的列表。
相关内容