다음을 통해 공유


연습: 서명 도움말 표시

서명 도움말 (도 매개 변수 정보) 사용자는 매개 변수 목록 시작 문자 (일반적으로 왼쪽 괄호)를 입력 하면 메서드의 시그니처에 도구 설명에 표시 됩니다. 매개 변수 및 매개 변수 구분 기호 (쉼표)를 입력할 때 도구 설명 다음 매개 변수가 굵게 표시 하도록 업데이트 됩니다. 언어 서비스의 컨텍스트에서 서명 하는 데 도움이 정의할 수 있습니다 또는 직접 파일 이름 확장명 및 콘텐츠 형식의 정의 하 고 해당 형식에 대해 표시할 서명 하는 데 도움이 있습니다 하거나 기존 콘텐츠 형식 (예를 들어, "text")에 서명 하는 데 도움이 표시할 수 있습니다. 이 연습에서는 "텍스트" 콘텐츠 형식에 서명 하는 데 도움이 표시 하는 방법을 보여 줍니다.

특정 문자, 예를 들어,을 입력 하 여 서명 도움말 트리거되는 일반적으로 "(" (괄호)와 다른 문자를 입력 하 여 해제 ")" (닫는 괄호)입니다. 키 입력에 대 한 명령 처리기를 사용 하 여 문자를 입력 하 여 트리거되는 IntelliSense 기능을 구현할 수 있습니다 (는 IOleCommandTarget 인터페이스) 및 구현 하는 처리기 공급자는 IVsTextViewCreationListener 인터페이스입니다. 서명 하는 데 도움이에서 참여 하는 서명 목록에서 서명 하는 데 도움이 소스를 만들기 위해 구현할는 ISignatureHelpSource 인터페이스와 구현 소스 공급자는 ISignatureHelpSourceProvider 인터페이스입니다. 공급자 확장 프레임 워크 (MEF) 관리 되는 구성 요소 이며 소스 및 컨트롤러 클래스를 내보낼 및 서비스 및 중개업 자, 예를 들어, 가져오기에 대 한 책임이 있습니다는 ITextStructureNavigatorSelectorService, 텍스트 버퍼에서 탐색할 수 및 ISignatureHelpBroker를 서명 하는 데 도움이 세션을 트리거합니다.

이 연습에서는 하드 코드 된 식별자 집합에 서명 하는 데 도움이 구현 하는 방법을 보여 줍니다. 모든 구현에서 언어 콘텐츠를 제공 하는 데 책임이 있습니다.

사전 요구 사항

이 연습을 완료 하려면 설치 해야 해당 Visual Studio 2010 SDK.

참고

Visual Studio SDK에 대 한 자세한 내용은 참조 하십시오. Visual Studio 개요를 확장합니다..Visual Studio SDK를 다운로드 하는 방법를 참조 하십시오. Visual Studio 확장성 개발자 센터 MSDN 웹 사이트에서.

MEF 프로젝트 만들기

MEF 프로젝트를 만들려면

  1. 편집기 분류자 프로젝트를 만듭니다. 솔루션의 이름을 SignatureHelpTest.

  2. VSIX 매니페스트 편집기에서 Source.extension.vsixmanifest 파일을 엽니다.

  3. Content MEF 구성 요소 콘텐츠 형식 및 해당 제목 포함은 Path Signaturehelptest.dll으로 설정 됩니다.

  4. 저장 하 고 source.extension.vsixmanifest를 닫습니다.

  5. 다음 참조를 프로젝트에 추가 하 고 설정 CopyLocal 에 false:

    Microsoft.VisualStudio.Editor

    Microsoft.VisualStudio.Language.Intellisense

    Microsoft.VisualStudio.OLE.Interop

    Microsoft.VisualStudio.Shell

    Microsoft.VisualStudio.TextManager.Interop

  6. 기존 클래스 파일을 삭제 합니다.

서명을 구현 시그니처 및 매개 변수

구현에서 서명을 서명 하는 데 도움이 소스를 기반으로 ISignature를 각각 구현 하는 매개 변수가 포함 된 IParameter. 완전 한 구현으로 언어 설명서에서이 정보를 얻을 수 있습니다 하드 코드 된이 예제에서는 서명이 됩니다.

서명 하는 데 도움이 되는 시그니처 및 매개 변수를 구현 하려면

  1. 클래스 파일을 추가 하 고 이름을 SignatureHelpSource.

  2. 다음 imports 추가 합니다.

    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;
    
  3. 라는 클래스를 추가 합니다. TestParameter 는 구현 IParameter.

    Friend Class TestParameter
        Implements IParameter
    
    internal class TestParameter : IParameter
    
  4. 모든 속성을 설정 하는 생성자를 추가 합니다.

    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;
    }
    
  5. 속성을 추가 합니다. 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; }
    
  6. 라는 클래스를 추가 합니다. TestSignature 는 구현 ISignature.

    Friend Class TestSignature
        Implements ISignature
    
    internal class TestSignature : ISignature
    
  7. Private 필드를 추가 합니다.

    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;
    
  8. 추가 필드를 설정 하 고 구독 하는 생성자는 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);
    }
    
  9. 선언 된 CurrentParameterChanged 이벤트입니다. 매개 변수 시그니처에서 중 하나에 사용자가 입력할 때이 이벤트가 발생 합니다.

    Public Event CurrentParameterChanged As EventHandler(Of CurrentParameterChangedEventArgs) Implements ISignature.CurrentParameterChanged
    
    public event EventHandler<CurrentParameterChangedEventArgs> CurrentParameterChanged;
    
  10. 구현에서 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);
            }
        }
    }
    
  11. 추가 발생 시키는 메서드는 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));
        }
    }
    
  12. 숫자에서 쉼표와 비교 하 여 현재 매개 변수를 계산 하는 메서드를 추가 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];
        }
    }
    
  13. 에 대 한 이벤트 처리기를 추가 Changed 를 호출 하는 이벤트는 ComputeCurrentParameter() 메서드.

    Friend Sub OnSubjectBufferChanged(ByVal sender As Object, ByVal e As TextContentChangedEventArgs)
        Me.ComputeCurrentParameter()
    End Sub
    
    internal void OnSubjectBufferChanged(object sender, TextContentChangedEventArgs e)
    {
        this.ComputeCurrentParameter();
    }
    
  14. 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; }
    }
    
  15. 다른 매개 변수를 구현 합니다.

    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; }
    }
    

서명 도움말 소스 구현

서명 하는 데 도움이 세트에 대 한 정보를 제공 하는 서명입니다.

서명 하는 데 도움이 소스를 구현 하려면

  1. 라는 클래스를 추가 합니다. TestSignatureHelpSource 는 구현 ISignatureHelpSource.

    Friend Class TestSignatureHelpSource
        Implements ISignatureHelpSource
    
    internal class TestSignatureHelpSource : ISignatureHelpSource
    
  2. 텍스트 버퍼에 대 한 참조를 추가 합니다.

    Private m_textBuffer As ITextBuffer
    
    private ITextBuffer m_textBuffer;
    
  3. 텍스트 버퍼 및 서명 하는 데 도움이 소스 공급자를 설정 하는 생성자를 추가 합니다.

    Public Sub New(ByVal textBuffer As ITextBuffer)
        m_textBuffer = textBuffer
    End Sub
    
    public TestSignatureHelpSource(ITextBuffer textBuffer)
    {
        m_textBuffer = textBuffer;
    }
    
  4. 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));
    
    }
    
  5. 도우미 메서드 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;
    }
    
  6. GetBestMatch 메서드를 구현합니다. 이 예제에는 각각 두 개의 매개 변수가 두 서명입니다. 따라서이 메서드는 필요 하지 않습니다. 서명 하는 데 도움이 두 개 이상의 소스에서 사용할 수 있는 보다 자세한 구현에서이 메서드는 일치 하는 서명이 서명 하는 데 도움이 하는 우선 순위가 가장 높은 소스를 제공할 수 있습니다 여부를 결정 합니다 사용 됩니다. 불가능 한 경우 메서드는 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
    
    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;
    }
    
  7. 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;
        }
    }
    

서명 도움말 소스 공급자 구현

원본 공급자가 서명 하는 데 도움이 및 서명 하는 데 도움이 소스를 인스턴스화하여 확장성 관리 프레임 워크 (MEF) 컴포넌트 부품 내보내기에 대 한 담당 합니다.

서명 하는 데 도움이 소스 공급자를 구현 하려면

  1. 라는 클래스를 추가 TestSignatureHelpSourceProvider 는 구현 ISignatureHelpSourceProvider, 함께 내보낼는 NameAttributea ContentTypeAttribute "텍스트" 하는 OrderAttribute 의 전 = "기본값"입니다.

    <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
    
  2. 구현 TryCreateSignatureHelpSource 에서 인스턴스화하는 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);
    }
    

명령 처리기를 구현합니다.

서명 도움말입니다 일반적으로 의해 트리거되는 (문자 및 dismissed가) 문자입니다. 구현 하 여 이러한 키 입력을 처리할 수는 IOleCommandTarget 받으면 서명 하는 데 도움이 세션 트리거하는 (문자는 알려진된 메서드 이름을 앞에 하 고 받으면 세션 해제 하는) 문자.

명령 처리기를 구현 하려면

  1. 라는 클래스를 추가 합니다. TestSignatureHelpCommand 는 구현 IOleCommandTarget.

    Friend NotInheritable Class TestSignatureHelpCommandHandler
        Implements IOleCommandTarget
    
    internal sealed class TestSignatureHelpCommandHandler : IOleCommandTarget
    
  2. Private 필드를 추가 IVsTextView (명령 처리기 체인의 명령 처리기를 추가할 수 있습니다) 어댑터, 텍스트 뷰, 서명 하는 데 도움이 되는 broker 및 세션을는 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;
    
  3. 이 필드를 초기화 하 고 명령을 필터 체인의 명령 필터를 추가 하는 생성자를 추가 합니다.

    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);
    }
    
  4. 구현은 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);
    }
    
  5. 구현에서 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 텍스트 뷰를 만들 때 명령 처리기를 인스턴스화할 수 합니다.

서명 하는 데 도움이 명령은 공급자를 구현 하려면

  1. 라는 클래스를 추가 합니다. TestSignatureHelpController 는 구현 IVsTextViewCreationListener 함께 내보낼는 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
    
  2. 가져오기는 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;
    
  3. 구현은 VsTextViewCreated 메서드에 의해 인스턴스화의 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));
    }
    

빌드 및 코드 테스트

이 코드를 테스트 하려면 SignatureHelpTest 솔루션을 빌드하고 실험 인스턴스를 실행 합니다.

빌드 및 SignatureHelpTest 솔루션을 테스트 하려면

  1. 솔루션을 빌드합니다.

  2. 이 프로젝트를 디버거에서 실행할 때 Visual Studio 두 번째 인스턴스를 인스턴스화합니다.

  3. 텍스트 파일 및 형식 단어 포함 된 일부 텍스트를 "추가"와 괄호를 만듭니다.

  4. 여는 괄호를 입력 한 후에 두 개의 서명 목록을 표시 하는 도구 설명이 표시 됩니다 있는 add() 메서드.

참고 항목

작업

연습: 콘텐츠 형식의 파일 이름 확장명에 연결