Passo a passo: Exibindo a Ajuda de assinatura
Ajuda de assinatura (também conhecido como Informações de parâmetro) exibe a assinatura de um método em uma dica de ferramenta quando um usuário digita o caractere de início de lista de parâmetro (normalmente um parêntese de abertura). Quando um parâmetro e o separador de parâmetro (geralmente uma vírgula) são digitados, a dica de ferramenta é atualizada para mostrar o próximo parâmetro em negrito. Você pode definir a assinatura ajudar no contexto de um serviço de idioma, você pode definir seu próprio tipo de conteúdo e a extensão de nome do arquivo e exibir a Ajuda de assinatura apenas desse tipo ou você pode exibir a Ajuda de assinatura para um tipo de conteúdo existente (por exemplo, "texto"). Esta explicação passo a passo mostra como exibir a Ajuda de assinatura para o tipo de conteúdo "text".
Ajuda de assinatura normalmente é acionada, digitando um caractere específico, por exemplo, "(" (parêntese de abertura) e dispensado digitando outro caractere, por exemplo, ")" (parêntese de fechamento). Recursos de IntelliSense que são acionados, digitando um caractere podem ser implementados usando um manipulador de comandos para os pressionamentos de teclas (o IOleCommandTarget interface) e um provedor de manipulador que implementa o IVsTextViewCreationListener interface. Para criar a fonte de ajuda de assinatura, que é a lista de assinaturas que participam da assinatura ajudar, implementar a ISignatureHelpSource interface e um provedor de origem que implementa o ISignatureHelpSourceProvider interface. Os provedores são partes do componente Managed Extensibility Framework (MEF) e são responsáveis por classes de origem e o controlador de exportação e importação de serviços e agentes, por exemplo, o ITextStructureNavigatorSelectorService, que permite que você navegue no buffer de texto, e o ISignatureHelpBroker, que dispara a sessão de ajuda de assinatura.
Esta explicação passo a passo mostra como implementar a assinatura ajuda para um conjunto de literais de identificadores. Em implementações completas, o idioma é responsável por fornecer esse conteúdo.
Pré-requisitos
Para concluir este passo a passo, você deve instalar o SDL do Visual Studio 2010.
Dica
Para obter mais informações sobre o SDK de Visual Studio, consulte Ampliando a visão geral de Visual Studio.Para descobrir como fazer o download do SDK do Visual Studio, consulte Visual Studio extensibilidade Developer Center no site do MSDN.
Criando um projeto MEF
Para criar um projeto MEF
Crie um projeto do classificador de Editor. Nomeie a solução SignatureHelpTest.
Abra o arquivo de Source.extension.vsixmanifest no Editor de VSIX de manifesto.
Certifique-se de que o Content título contém um tipo de conteúdo do componente MEF e que o Path for definido como SignatureHelpTest.dll.
Salve e feche o Source.extension.vsixmanifest.
Adicione as seguintes referências ao projeto e defina CopyLocal para false:
Microsoft.VisualStudio.Editor
Microsoft.VisualStudio.Language.IntelliSense
Microsoft.VisualStudio.OLE.Interop
Microsoft.VisualStudio.Shell
Microsoft.VisualStudio.TextManager.Interop
Exclua os arquivos de classe existentes.
Implementando a assinatura ajuda assinaturas e parâmetros
Fonte de assinatura se baseia em assinaturas que implementam ISignature, cada um deles contém parâmetros que implementam IParameter. Em uma implementação completa, essa informação seria obtida com a documentação do idioma, mas neste exemplo, as assinaturas são codificados.
Para implementar a assinatura ajudar assinaturas e os parâmetros
Adicione um arquivo de classe e denomine- SignatureHelpSource.
Adicione as importações a seguintes.
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;
Adicionar uma classe chamada TestParameter que implementa IParameter.
Friend Class TestParameter Implements IParameter
internal class TestParameter : IParameter
Adicione um construtor que defina todas as propriedades.
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; }
Adicione as propriedades de 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; }
Adicionar uma classe chamada TestSignature que implementa ISignature.
Friend Class TestSignature Implements ISignature
internal class TestSignature : ISignature
Adicione alguns campos privados.
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;
Adicionar um construtor que define os campos e assina o Changed evento.
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); }
Declarar um CurrentParameterChanged evento. Este evento é gerado quando o usuário preenche um dos parâmetros na assinatura.
Public Event CurrentParameterChanged As EventHandler(Of CurrentParameterChangedEventArgs) Implements ISignature.CurrentParameterChanged
public event EventHandler<CurrentParameterChangedEventArgs> CurrentParameterChanged;
Implementar a CurrentParameter propriedade, de modo que ele gera a CurrentParameterChanged evento quando o valor da propriedade é alterado.
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); } } }
Adicionar um método que gera a CurrentParameterChanged evento.
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)); } }
Adicionar um método que computa o parâmetro atual, comparando o número de vírgulas na ApplicableToSpan o número de vírgulas na assinatura.
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]; } }
Adiciona um manipulador para o Changed o evento que chama o ComputeCurrentParameter() método.
Friend Sub OnSubjectBufferChanged(ByVal sender As Object, ByVal e As TextContentChangedEventArgs) Me.ComputeCurrentParameter() End Sub
internal void OnSubjectBufferChanged(object sender, TextContentChangedEventArgs e) { this.ComputeCurrentParameter(); }
Implementar a ApplicableToSpan propriedade. Esta propriedade contém um ITrackingSpan que corresponde ao trecho de texto no buffer ao qual se aplica a assinatura.
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; } }
Implemente os outros parâmetros.
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; } }
Implementando a fonte de ajuda de assinatura
Fonte de assinatura é o conjunto de assinaturas para o qual você pode fornecer informações.
Para implementar a fonte de assinatura
Adicionar uma classe chamada TestSignatureHelpSource que implementa ISignatureHelpSource.
Friend Class TestSignatureHelpSource Implements ISignatureHelpSource
internal class TestSignatureHelpSource : ISignatureHelpSource
Adicione uma referência para o buffer de texto.
Private m_textBuffer As ITextBuffer
private ITextBuffer m_textBuffer;
Adicione um construtor que defina o buffer de texto e o provedor de origem ajuda a assinatura.
Public Sub New(ByVal textBuffer As ITextBuffer) m_textBuffer = textBuffer End Sub
public TestSignatureHelpSource(ITextBuffer textBuffer) { m_textBuffer = textBuffer; }
Implemente o método AugmentSignatureHelpSession. Neste exemplo, as assinaturas são codificados, mas uma implementação completa, você obteria essas informações da documentação do idioma.
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)); }
O método auxiliar CreateSignature() é fornecido apenas para ilustração.
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; }
Implemente o método GetBestMatch. Neste exemplo, existem apenas duas assinaturas, cada um deles tem dois parâmetros. Portanto, esse método não é necessário. Em uma implementação maior, em que mais de uma fonte de ajuda de assinatura está disponível, este método é usado para decidir se a fonte de ajuda de assinatura de maior prioridade pode fornecer uma assinatura correspondente. Se não for possível, o método retorna null e a fonte de Avançar mais alta prioridade é solicitada a fornecer uma correspondência.
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; }
Implemente o método 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; } }
Implementando o provedor de origem da Ajuda de assinatura
O provedor de origem ajuda a assinatura é responsável pelo exportação a parte do componente Managed Extensibility Framework (MEF) e para criar instâncias de fonte de assinatura.
Para implementar um provedor de origem ajuda de assinatura
Adicionar uma classe chamada TestSignatureHelpSourceProvider que implementa ISignatureHelpSourceProvidere exportá-lo com um NameAttribute, um ContentTypeAttribute de "texto" e um OrderAttribute de antes de = "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
Implementar TryCreateSignatureHelpSource instanciando o TestSignatureHelpSource.
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); }
Implementando o manipulador de comandos
Ajuda de assinatura normalmente é disparada por uma (caractere e demitidos por uma) caracteres. Você pode manipular esses pressionamentos de tecla, Implementando um IOleCommandTarget para que ele dispara uma sessão de ajuda de assinatura quando ela recebe um (caractere precedido por um nome de método conhecidos e descarta a sessão quando recebe um) caracteres.
Para implementar o manipulador de comandos
Adicionar uma classe chamada TestSignatureHelpCommand que implementa IOleCommandTarget.
Friend NotInheritable Class TestSignatureHelpCommandHandler Implements IOleCommandTarget
internal sealed class TestSignatureHelpCommandHandler : IOleCommandTarget
Adicionar campos privados para o IVsTextView adaptador (que permite a você adicionar o manipulador de comando para os manipuladores de cadeia de comando), o modo de exibição de texto, a assinatura ajudar broker e a sessão, um ITextStructureNavigatore o próximo 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;
Adicione um construtor para inicializar esses campos e adicionar o filtro de comando com os filtros de cadeia de comando.
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); }
Implementar a Exec método para disparar a sessão de ajuda de assinatura quando o filtro de comando recebe um (caractere depois que um dos nomes de método conhecidos e para descartar a sessão quando recebe um) de caracteres enquanto a sessão ainda estiver ativa. Em cada caso, o comando é encaminhado.
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); }
Implementar a QueryStatus , de modo que ele sempre encaminha o comando de método.
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); }
Implementando o provedor de comando de ajuda de assinatura
Você pode fornecer o comando Help de assinatura, Implementando o IVsTextViewCreationListener para instanciar o manipulador de comandos quando o modo de exibição de texto é criado.
Para implementar o provedor de comando Ajuda de assinatura
Adicionar uma classe chamada TestSignatureHelpController que implementa IVsTextViewCreationListener e exportá-lo com o NameAttribute, ContentTypeAttribute, e 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
Importar o IVsEditorAdaptersFactoryService (usado para obter o ITextView, dado o IVsTextView objeto), o ITextStructureNavigatorSelectorService (usado para localizar a palavra atual) e o ISignatureHelpBroker (para acionar a sessão de ajuda de assinatura).
<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;
Implementar a VsTextViewCreated método instanciando o TestSignatureCommandHandler.
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)); }
Criar e testar o código
Para testar esse código, crie a solução de SignatureHelpTest e execute-o na instância experimental.
Para criar e testar a solução de SignatureHelpTest
Crie a solução.
Ao executar este projeto no depurador, uma segunda instância do Visual Studio é instanciada.
Crie um arquivo de texto e um parêntese de abertura além de tipo algum texto que inclui a palavra "Adicionar".
Após digitar o parêntese de abertura, você deverá ver uma dica de ferramenta que exibe uma lista de duas assinaturas para a add() método.
Consulte também
Tarefas
Passo a passo: Vinculação a um tipo de conteúdo a uma extensão de nome de arquivo