Condividi tramite


procedura dettagliata: Visualizzazione di completamento delle istruzioni

È possibile distribuire le funzionalità a livello di linguaggio quali il completamento delle istruzioni definizione di identificatori per il quale si desidera fornire il completamento e quindi su una sessione di completamento. È possibile definire il completamento delle istruzioni nel contesto di un servizio di linguaggio, oppure è possibile definire diventi proprietaria l'estensione di file e tipo di contenuto e completamento della visualizzazione solo per tale tipo, oppure è possibile attivare il completamento di un tipo di contenuto esistente (ad esempio “solo testo„). In questa procedura dettagliata viene illustrato come attivare il completamento di istruzioni per il tipo di contenuto “non crittografato„, che è il tipo di contenuto di un file di testo. Il tipo di contenuto “text„ è il predecessore di tutti gli altri tipi di contenuto, incluso il codice e file XML.

Il completamento di istruzioni in genere viene attivato digitando determinati caratteri, ad esempio, digitando l'inizio di un identificatore come “utilizzando„. In genere viene chiusa premendo BARRA SPAZIATRICE, TAB, o INVIO per eseguire il commit di una selezione. Le funzionalità di IntelliSense che vengono attivate digitando un carattere possono essere distribuite tramite un gestore comando per le sequenze di tasti (l'interfaccia di IOleCommandTarget ) e un provider del gestore che implementa l'interfaccia di IVsTextViewCreationListener . Per creare l'origine di completamento, che è l'elenco degli identificatori che partecipano al completamento, implementare l'interfaccia di ICompletionSource e un provider di origine di completamento (l'interfaccia di ICompletionSourceProvider ). I provider sono elementi gestiti (MEF) del Framework di estensibilità e sono responsabili dell'esportazione del database di origine e classi controller e di includere i servizi e i Service Broker, ad esempio, ITextStructureNavigatorSelectorService, che consente di spostarsi nel buffer di testo e ICompletionBroker, che genera la sessione di completamento.

In questa procedura dettagliata viene illustrato come implementare completamento delle istruzioni per un set specificato a livello di codice di identificatori. Nelle implementazioni complete, il servizio di linguaggio e la documentazione del linguaggio sono responsabili della visualizzazione del contenuto.

Prerequisiti

Per completare questa procedura dettagliata, è necessario installare Visual Studio 2010 SDK.

Nota

per ulteriori informazioni su Visual Studio SDK, vedere Cenni preliminari sull'estensione di Visual Studio.Per ulteriori informazioni su come scaricare Visual Studio SDK, vedere Centro per sviluppatori di estensibilità di Visual Studio il sito Web MSDN.

Creare un progetto MEF

Per creare un progetto MEF

  1. Creare un progetto di classificatore editor. Assegnare alla soluzione CompletionTest.

  2. Aprire il file source.extension.vsixmanifest nell'editor del manifesto VSIX.

  3. Assicurarsi che la direzione di contenuto contenga un tipo di contenuto di Componente MEF e che percorso è impostato su CompletionTest.dll.

  4. salvare e chiudere source.extension.vsixmanifest.

  5. Aggiungere i seguenti riferimenti al progetto e assicurarsi che CopyLocal sia impostata su false:

    Microsoft.VisualStudio.Editor

    Microsoft.VisualStudio.Language.Intellisense

    Microsoft.VisualStudio.OLE.Interop

    Microsoft.VisualStudio.Shell.10.0

    Microsoft.VisualStudio.Shell.Immutable.10.0

    Microsoft.VisualStudio.TextManager.Interop

  6. Eliminare i file di classe esistenti.

Distribuire il database di origine di completamento

L'origine di completamento è responsabile della raccolta del set di identificatori e dell'aggiunta di contenuto alla finestra di completamento quando si digita un trigger di completamento, ad esempio le prime lettere di un identificatore. In questo esempio, gli identificatori e le relative descrizioni sono specificati nel metodo diAugmentCompletionSession . In utilizza più realistici, si utilizzerebbe il parser del linguaggio per ottenere i token per compilare l'elenco di completamento.

Per distribuire il database di origine di completamento

  1. Aggiungere il file di classe e denominarlo TestCompletionSource.

  2. Aggiungere i seguenti elementi importati.

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.ComponentModel.Composition
    Imports Microsoft.VisualStudio.Language.Intellisense
    Imports Microsoft.VisualStudio.Text
    Imports Microsoft.VisualStudio.Text.Operations
    Imports Microsoft.VisualStudio.Utilities
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio.Language.Intellisense;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Operations;
    using Microsoft.VisualStudio.Utilities;
    
  3. Modificare la dichiarazione di classe per TestCompletionSource in modo che venga distribuito ICompletionSource.

    Friend Class TestCompletionSource
        Implements ICompletionSource
    
    internal class TestCompletionSource : ICompletionSource
    
  4. Aggiungere campi privati per il provider di origine, il buffer di testo e un elenco di oggetti di Completion (che corrispondono agli identificatori che prenderanno parte alla sessione di completamento).

    Private m_sourceProvider As TestCompletionSourceProvider
    Private m_textBuffer As ITextBuffer
    Private m_compList As List(Of Completion)
    
    private TestCompletionSourceProvider m_sourceProvider;
    private ITextBuffer m_textBuffer;
    private List<Completion> m_compList;
    
  5. Aggiungere un costruttore che imposta il provider di origine e il buffer. La classe di TestCompletionSourceProvider è definita nei passaggi successivi.

    Public Sub New(ByVal sourceProvider As TestCompletionSourceProvider, ByVal textBuffer As ITextBuffer)
        m_sourceProvider = sourceProvider
        m_textBuffer = textBuffer
    End Sub
    
    public TestCompletionSource(TestCompletionSourceProvider sourceProvider, ITextBuffer textBuffer)
    {
        m_sourceProvider = sourceProvider;
        m_textBuffer = textBuffer;
    }
    
  6. Implementare il metodo di AugmentCompletionSession aggiungendo il completamento impostato contenente i completamenti che si desidera fornire il contesto. Ogni set di completamenti contiene un set di completamenti di Completion e corrisponde a una scheda della finestra di completamento. (Nei progetti di Visual Basic., schede di completamento della finestra sono denominate Comune e Tutto). Il metodo di FindTokenSpanAtPosition è definito nel passaggio successivo.

    Private Sub AugmentCompletionSession(ByVal session As ICompletionSession, ByVal completionSets As IList(Of CompletionSet)) Implements ICompletionSource.AugmentCompletionSession
        Dim strList As New List(Of String)()
        strList.Add("addition")
        strList.Add("adaptation")
        strList.Add("subtraction")
        strList.Add("summation")
    
        m_compList = New List(Of Completion)()
        For Each str As String In strList
            m_compList.Add(New Completion(str, str, str, Nothing, Nothing))
        Next str
    
        completionSets.Add(New CompletionSet(
            "Tokens",
            "Tokens",
            FindTokenSpanAtPosition(session.GetTriggerPoint(m_textBuffer),
                session),
            m_compList,
            Nothing))
    End Sub
    
    void ICompletionSource.AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets)
    {
        List<string> strList = new List<string>();
        strList.Add("addition");
        strList.Add("adaptation");
        strList.Add("subtraction");
        strList.Add("summation");
        m_compList = new List<Completion>();
        foreach (string str in strList)
            m_compList.Add(new Completion(str, str, str, null, null));
    
        completionSets.Add(new CompletionSet(
            "Tokens",    //the non-localized title of the tab 
            "Tokens",    //the display title of the tab
            FindTokenSpanAtPosition(session.GetTriggerPoint(m_textBuffer),
                session),
            m_compList,
            null));
    }
    
  7. Il metodo seguente viene utilizzato per trovare la parola corrente dalla posizione del cursore.

    Private Function FindTokenSpanAtPosition(ByVal point As ITrackingPoint, ByVal session As ICompletionSession) As ITrackingSpan
        Dim currentPoint As SnapshotPoint = (session.TextView.Caret.Position.BufferPosition) - 1
        Dim navigator As ITextStructureNavigator = m_sourceProvider.NavigatorService.GetTextStructureNavigator(m_textBuffer)
        Dim extent As TextExtent = navigator.GetExtentOfWord(currentPoint)
        Return currentPoint.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive)
    End Function
    
    private ITrackingSpan FindTokenSpanAtPosition(ITrackingPoint point, ICompletionSession session)
    {
        SnapshotPoint currentPoint = (session.TextView.Caret.Position.BufferPosition) - 1;
        ITextStructureNavigator navigator = m_sourceProvider.NavigatorService.GetTextStructureNavigator(m_textBuffer);
        TextExtent extent = navigator.GetExtentOfWord(currentPoint);
        return currentPoint.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive);
    }
    
  8. implementare il metodo di 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;
        }
    }
    

implementare il provider di origine di completamento

Il provider di origine di completamento è l'elemento MEF che crea un'istanza del database di origine di completamento.

Per implementare il provider di origine di completamento

  1. Aggiungere TestCompletionSourceProvider classe denominata che implementa ICompletionSourceProvider. Esportare questa classe con ContentTypeAttribute “di solo testo„ e NameAttribute “di completamento del test„.

    <Export(GetType(ICompletionSourceProvider)), ContentType("plaintext"), Name("token completion")>
    Friend Class TestCompletionSourceProvider
        Implements ICompletionSourceProvider
    
    [Export(typeof(ICompletionSourceProvider))]
    [ContentType("plaintext")]
    [Name("token completion")]
    internal class TestCompletionSourceProvider : ICompletionSourceProvider
    
  2. Importare ITextStructureNavigatorSelectorService, che deve essere utilizzato per trovare la parola corrente nel database di origine di completamento.

    <Import()>
    Friend Property NavigatorService() As ITextStructureNavigatorSelectorService
    
    [Import]
    internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
    
  3. Implementare il metodo di TryCreateCompletionSource per creare un'istanza del database di origine di completamento.

    Public Function TryCreateCompletionSource(ByVal textBuffer As ITextBuffer) As ICompletionSource Implements ICompletionSourceProvider.TryCreateCompletionSource
        Return New TestCompletionSource(Me, textBuffer)
    End Function
    
    public ICompletionSource TryCreateCompletionSource(ITextBuffer textBuffer)
    {
        return new TestCompletionSource(this, textBuffer);
    }
    

Implementare il provider di completamento del gestore comando

Il provider di completamento del gestore comando è derivato da IVsTextViewCreationListener, in ascolto di un evento di creazione della visualizzazione di testo e converte la visualizzazione da IVsTextView (che consente il comando aggiungere alla catena di comando della shell di Visual Studio) a ITextView. Poiché questa classe è un'esportazione MEF, è possibile utilizzarlo anche per includere i servizi che saranno necessari dal gestore comando stesso.

Per implementare il provider di completamento del gestore comando

  1. aggiungere un file denominato TestCompletionCommandHandler.

  2. Aggiungere le istruzioni using riportate di seguito.

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.ComponentModel.Composition
    Imports System.Runtime.InteropServices
    Imports Microsoft.VisualStudio
    Imports Microsoft.VisualStudio.Editor
    Imports Microsoft.VisualStudio.Language.Intellisense
    Imports Microsoft.VisualStudio.OLE.Interop
    Imports Microsoft.VisualStudio.Shell
    Imports Microsoft.VisualStudio.Text
    Imports Microsoft.VisualStudio.Text.Editor
    Imports Microsoft.VisualStudio.TextManager.Interop
    Imports Microsoft.VisualStudio.Utilities
    
    using System;
    using System.ComponentModel.Composition;
    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Editor;
    using Microsoft.VisualStudio.Language.Intellisense;
    using Microsoft.VisualStudio.OLE.Interop;
    using Microsoft.VisualStudio.Shell;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.TextManager.Interop;
    using Microsoft.VisualStudio.Utilities;
    
  3. Aggiungere TestCompletionHandlerProvider classe denominata che implementa IVsTextViewCreationListener. Esportare questa classe con NameAttribute “del gestore di completamento token„, ContentTypeAttribute “di solo testo„ e TextViewRoleAttribute di Editable.

    <Export(GetType(IVsTextViewCreationListener))>
    <Name("token completion handler")>
    <ContentType("plaintext")> <TextViewRole(PredefinedTextViewRoles.Editable)>
    Friend Class TestCompletionHandlerProvider
        Implements IVsTextViewCreationListener
    
    [Export(typeof(IVsTextViewCreationListener))]
    [Name("token completion handler")]
    [ContentType("plaintext")]
    [TextViewRole(PredefinedTextViewRoles.Editable)]
    internal class TestCompletionHandlerProvider : IVsTextViewCreationListener
    
  4. Importare IVsEditorAdaptersFactoryService, che consente di convertire da IVsTextView a ITextView, a ICompletionBrokere a SVsServiceProvider, che consente l'accesso ai servizi standard di accesso di Visual Studio.

    <Import()>
    Friend AdapterService As IVsEditorAdaptersFactoryService = Nothing
    <Import()>
    Friend Property CompletionBroker() As ICompletionBroker
    <Import()>
    Friend Property ServiceProvider() As SVsServiceProvider
    
    [Import]
    internal IVsEditorAdaptersFactoryService AdapterService = null;
    [Import]
    internal ICompletionBroker CompletionBroker { get; set; }
    [Import]
    internal SVsServiceProvider ServiceProvider { get; set; }
    
  5. Implementare il metodo di VsTextViewCreated per creare un'istanza del gestore comando.

    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 
    
        Dim createCommandHandler As Func(Of TestCompletionCommandHandler) = Function() New TestCompletionCommandHandler(textViewAdapter, textView, Me)
        textView.Properties.GetOrCreateSingletonProperty(createCommandHandler)
    End Sub
    
    public void VsTextViewCreated(IVsTextView textViewAdapter)
    {
        ITextView textView = AdapterService.GetWpfTextView(textViewAdapter);
        if (textView == null)
            return;
    
        Func<TestCompletionCommandHandler> createCommandHandler = delegate() { return new TestCompletionCommandHandler(textViewAdapter, textView, this); };
        textView.Properties.GetOrCreateSingletonProperty(createCommandHandler);
    }
    

Implementazione del gestore comando di completamento

Poiché il completamento delle istruzioni è attivato dalle sequenze di tasti, è necessario implementare l'interfaccia di IOleCommandTarget per ricevere ed elaborare le sequenze di tasti che attivano, esegue il commit e chiudere la sessione di completamento.

Per implementare il gestore comando di completamento

  1. Aggiungere TestCompletionCommandHandler classe denominata che implementa IOleCommandTarget.

    Friend Class TestCompletionCommandHandler
        Implements IOleCommandTarget
    
    internal class TestCompletionCommandHandler : IOleCommandTarget
    
  2. Aggiungere campi privati per il gestore comando seguente (che viene passato al comando), la visualizzazione di testo, il provider del gestore comando (che consente di accedere a diversi servizi) e una sessione di completamento.

    Private m_nextCommandHandler As IOleCommandTarget
    Private m_textView As ITextView
    Private m_provider As TestCompletionHandlerProvider
    Private m_session As ICompletionSession
    
    private IOleCommandTarget m_nextCommandHandler;
    private ITextView m_textView;
    private TestCompletionHandlerProvider m_provider;
    private ICompletionSession m_session;
    
  3. Aggiungere un costruttore che imposta la visualizzazione di testo e campi del provider e aggiunto il comando nella catena di comando.

    Friend Sub New(ByVal textViewAdapter As IVsTextView, ByVal textView As ITextView, ByVal provider As TestCompletionHandlerProvider)
        Me.m_textView = textView
        Me.m_provider = provider
    
        'add the command to the command chain
        textViewAdapter.AddCommandFilter(Me, m_nextCommandHandler)
    End Sub
    
    internal TestCompletionCommandHandler(IVsTextView textViewAdapter, ITextView textView, TestCompletionHandlerProvider provider)
    {
        this.m_textView = textView;
        this.m_provider = provider;
    
        //add the command to the command chain
        textViewAdapter.AddCommandFilter(this, out m_nextCommandHandler);
    }
    
  4. Implementare il metodo di QueryStatus passando il comando in avanti.

    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);
    }
    
  5. Implementare il metodo Exec. Quando questo metodo riceve un tasto, deve effettuare una delle seguenti operazioni:

    • Consentire il carattere da scrivere nel buffer e quindi attivare o filtrare il completamento (i caratteri di stampa questa operazione).

    • Eseguire il commit del completamento, ma non consentire il carattere da scrivere nel buffer (vuoto, CATALOGARE e all'INVIO questa operazione quando una sessione di completamento video).

    • Consentire il comando essere passato al gestore successivo (tutti gli altri controlli.

    Poiché questo metodo può visualizzare l'interfaccia utente, è necessario assicurarsi che non sia chiamata in un contesto di automazione chiamando IsInAutomationFunction.

    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
        If VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider) Then 
            Return m_nextCommandHandler.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)
        End If 
        'make a copy of this so we can look at it after forwarding some commands 
        Dim commandID As UInteger = nCmdID
        Dim typedChar As Char = Char.MinValue
        'make sure the input is a char before getting it 
        If pguidCmdGroup = VSConstants.VSStd2K AndAlso nCmdID = CUInt(VSConstants.VSStd2KCmdID.TYPECHAR) Then
            typedChar = CChar(ChrW(CUShort(Marshal.GetObjectForNativeVariant(pvaIn))))
        End If 
    
        'check for a commit character 
        If nCmdID = CUInt(VSConstants.VSStd2KCmdID.RETURN) OrElse nCmdID = CUInt(VSConstants.VSStd2KCmdID.TAB) OrElse (Char.IsWhiteSpace(typedChar) OrElse Char.IsPunctuation(typedChar)) Then 
            'check for a a selection 
            If m_session IsNot Nothing AndAlso (Not m_session.IsDismissed) Then 
                'if the selection is fully selected, commit the current session 
                If m_session.SelectedCompletionSet.SelectionStatus.IsSelected Then
                    m_session.Commit()
                    'also, don't add the character to the buffer 
                    Return VSConstants.S_OK
                Else 
                    'if there is no selection, dismiss the session
                    m_session.Dismiss()
                End If 
            End If 
        End If 
    
        'pass along the command so the char is added to the buffer 
        Dim retVal As Integer = m_nextCommandHandler.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)
        Dim handled As Boolean = False 
        If (Not typedChar.Equals(Char.MinValue)) AndAlso Char.IsLetterOrDigit(typedChar) Then 
            If m_session Is Nothing OrElse m_session.IsDismissed Then ' If there is no active session, bring up completion
                Me.TriggerCompletion()
                m_session.Filter()
            Else 'the completion session is already active, so just filter
                m_session.Filter()
            End If
            handled = True 
        ElseIf commandID = CUInt(VSConstants.VSStd2KCmdID.BACKSPACE) OrElse commandID = CUInt(VSConstants.VSStd2KCmdID.DELETE) Then 'redo the filter if there is a deletion
            If m_session IsNot Nothing AndAlso (Not m_session.IsDismissed) Then
                m_session.Filter()
            End If
            handled = True 
        End If 
        If handled Then 
            Return VSConstants.S_OK
        End If 
        Return retVal
    End Function
    
    public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
    {
        if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
        {
            return m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
        }
        //make a copy of this so we can look at it after forwarding some commands 
        uint commandID = nCmdID;
        char typedChar = char.MinValue;
        //make sure the input is a char before getting it 
        if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
        {
            typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
        }
    
        //check for a commit character 
        if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN
            || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB
            || (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar)))
        {
            //check for a a selection 
            if (m_session != null && !m_session.IsDismissed)
            {
                //if the selection is fully selected, commit the current session 
                if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                {
                    m_session.Commit();
                    //also, don't add the character to the buffer 
                    return VSConstants.S_OK;
                }
                else
                {
                    //if there is no selection, dismiss the session
                    m_session.Dismiss();
                }
            }
        }
    
        //pass along the command so the char is added to the buffer 
        int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
        bool handled = false;
        if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar))
        {
            if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion
            {
                this.TriggerCompletion();
                m_session.Filter();
            }
            else     //the completion session is already active, so just filter
            {
                m_session.Filter();
            }
            handled = true;
        }
        else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE   //redo the filter if there is a deletion
            || commandID == (uint)VSConstants.VSStd2KCmdID.DELETE)
        {
            if (m_session != null && !m_session.IsDismissed)
                m_session.Filter();
            handled = true;
        }
        if (handled) return VSConstants.S_OK;
        return retVal;
    }
    
  6. Il codice seguente è un metodo privato che attiva la sessione di completamento.

    Private Function TriggerCompletion() As Boolean 
        'the caret must be in a non-projection location  
        Dim caretPoint As SnapshotPoint? = m_textView.Caret.Position.Point.GetPoint(Function(textBuffer) ((Not textBuffer.ContentType.IsOfType("projection"))), PositionAffinity.Predecessor)
        If Not caretPoint.HasValue Then 
            Return False 
        End If
    
        m_session = m_provider.CompletionBroker.CreateCompletionSession(m_textView, caretPoint.Value.Snapshot.CreateTrackingPoint(caretPoint.Value.Position, PointTrackingMode.Positive), True)
    
        'subscribe to the Dismissed event on the session  
        AddHandler m_session.Dismissed, AddressOf OnSessionDismissed
        m_session.Start()
    
        Return True 
    End Function
    
    private bool TriggerCompletion()
    {
        //the caret must be in a non-projection location 
        SnapshotPoint? caretPoint =
        m_textView.Caret.Position.Point.GetPoint(
        textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor);
        if (!caretPoint.HasValue)
        {
            return false;
        }
    
        m_session = m_provider.CompletionBroker.CreateCompletionSession
     (m_textView,
            caretPoint.Value.Snapshot.CreateTrackingPoint(caretPoint.Value.Position, PointTrackingMode.Positive),
            true);
    
        //subscribe to the Dismissed event on the session 
        m_session.Dismissed += this.OnSessionDismissed;
        m_session.Start();
    
        return true;
    }
    
  7. Il codice seguente è un metodo privato che disdice dall'evento di Dismissed .

    Private Sub OnSessionDismissed(ByVal sender As Object, ByVal e As EventArgs)
        RemoveHandler m_session.Dismissed, AddressOf OnSessionDismissed
        m_session = Nothing 
    End Sub
    
    private void OnSessionDismissed(object sender, EventArgs e)
    {
        m_session.Dismissed -= this.OnSessionDismissed;
        m_session = null;
    }
    

Compilazione e test del codice

Per testare questo codice, compilare la soluzione di CompletionTest ed eseguirla nell'istanza sperimentale.

Per compilare e testare la soluzione di CompletionTest

  1. Compilare la soluzione.

  2. Quando si esegue il progetto nel debugger, una seconda istanza di Visual Studio viene creata un'istanza.

  3. Creare un file di testo e digitare un testo che include la parola “add„.

  4. Non appena digitato innanzitutto “a„ e “d„, un elenco contenente “add„ e “l'adattamento„ deve essere visualizzato. Si noti che l'aggiunta è selezionata. Quando si digita un'altra “d„, l'elenco deve contenere solo “add„, che è selezionata. È possibile applicare “add„ premendo BARRA SPAZIATRICE, CATALOGARE, o INVIO, o chiudere l'elenco digitando ESC o qualsiasi altro carattere.

Vedere anche

Attività

procedura dettagliata: Collegare un tipo di contenuto a un'estensione di file