연습: 서명 도움말 표시Walkthrough: Display Signature Help
서명 도움말 ( 매개 변수 정보 라고도 함)은 사용자가 매개 변수 목록 시작 문자 (일반적으로 여는 괄호)를 입력 하는 경우 도구 설명에 메서드의 시그니처를 표시 합니다.Signature Help (also known as Parameter Info) displays the signature of a method in a tooltip when a user types the parameter list start character (typically an opening parenthesis). 매개 변수 및 매개 변수 구분 기호 (일반적으로 쉼표)가 입력 되 면 도구 설명이 업데이트 되어 다음 매개 변수가 굵게 표시 됩니다.As a parameter and parameter separator (typically a comma) are typed, the tooltip is updated to show the next parameter in bold. 다음과 같은 방법으로 시그니처 도움말을 정의할 수 있습니다. 언어 서비스 컨텍스트에서 고유한 파일 이름 확장명 및 콘텐츠 형식을 정의 하 고 해당 형식에 대 한 서명 도움말을 표시 하거나 기존 콘텐츠 형식 (예: "텍스트")에 대 한 서명 도움말을 표시 합니다.You can define Signature Help in the following ways: in the context of a language service, define your own file name extension and content type and display Signature Help for just that type, or display Signature Help for an existing content type (for example, "text"). 이 연습에서는 "text" 콘텐츠 형식에 대 한 시그니처 도움말을 표시 하는 방법을 보여 줍니다.This walkthrough shows how to display Signature Help for the "text" content type.
서명 도움말은 일반적으로 특정 문자 (예: "(") (여는 괄호)를 입력 하 여 트리거되고 다른 문자 (예: ")" (닫는 괄호)를 입력 하 여 해제 됩니다.Signature Help is typically triggered by typing a specific character, for example, "(" (opening parenthesis), and dismissed by typing another character, for example, ")" (closing parenthesis). 문자를 입력 하 여 트리거되는 IntelliSense 기능은 키 입력 ( IOleCommandTarget 인터페이스) 및 인터페이스를 구현 하는 처리기 공급자에 대해 명령 처리기를 사용 하 여 구현할 수 있습니다 IVsTextViewCreationListener .IntelliSense features that are triggered by typing a character can be implemented by using a command handler for the keystrokes (the IOleCommandTarget interface) and a handler provider that implements the IVsTextViewCreationListener interface. 서명 도움말에 참여 하는 서명 목록에 해당 하는 서명 도움말 원본을 만들려면 인터페이스 ISignatureHelpSource 와 인터페이스를 실행 하는 소스 공급자를 구현 합니다 ISignatureHelpSourceProvider .To create the Signature Help source, which is the list of signatures that participate in Signature Help, implement the ISignatureHelpSource interface and a source provider that runs the ISignatureHelpSourceProvider interface. 공급자는 MEF (Managed Extensibility Framework) 구성 요소 부분으로, 소스 및 컨트롤러 클래스를 내보내고 서비스와 broker를 가져옵니다. 예를 들어, ITextStructureNavigatorSelectorService 텍스트 버퍼에서 탐색할 수 있는 및 서명 도움말 세션을 트리거하는를 사용할 수 있습니다 ISignatureHelpBroker .The providers are Managed Extensibility Framework (MEF) component parts, and are responsible for exporting the source and controller classes and importing services and brokers, for example, the ITextStructureNavigatorSelectorService, which lets you navigate in the text buffer, and the ISignatureHelpBroker, which triggers the Signature Help session.
이 연습에서는 하드 코드 된 식별자 집합에 대 한 시그니처 도움말을 설정 하는 방법을 보여 줍니다.This walkthrough shows how to set up Signature Help for a hard-coded set of identifiers. 모든 구현에서이 언어는 해당 콘텐츠를 제공 합니다.In full implementations, the language is responsible for providing that content.
사전 준비 사항Prerequisites
Visual Studio 2015 부터는 다운로드 센터에서 Visual Studio SDK를 설치 하지 않습니다.Starting in Visual Studio 2015, you don't install the Visual Studio SDK from the download center. Visual Studio 설치 프로그램에서 선택적 기능으로 포함 되어 있습니다.It's included as an optional feature in Visual Studio setup. VS SDK는 나중에 설치할 수도 있습니다.You can also install the VS SDK later on. 자세한 내용은 Visual STUDIO SDK 설치를 참조 하세요.For more information, see Install the Visual Studio SDK.
MEF 프로젝트 만들기Creating a MEF project
MEF 프로젝트를 만들려면To create a MEF project
C # VSIX 프로젝트를 만듭니다.Create a C# VSIX project. ( 새 프로젝트 대화 상자에서 Visual c #/확장성, VSIX 프로젝트 를 차례로 선택 합니다.) 솔루션 이름을로
SignatureHelpTest
합니다.(In the New Project dialog, select Visual C# / Extensibility, then VSIX Project.) Name the solutionSignatureHelpTest
.편집기 분류자 항목 템플릿을 프로젝트에 추가 합니다.Add an Editor Classifier item template to the project. 자세한 내용은 편집기 항목 템플릿을 사용 하 여 확장 만들기를 참조 하세요.For more information, see Create an extension with an editor item template.
기존 클래스 파일을 삭제합니다.Delete the existing class files.
프로젝트에 다음 참조를 추가 하 고 CopyLocal 이로 설정 되었는지 확인 합니다
false
.Add the following references to the project, and make sure CopyLocal is set tofalse
:VisualStudioMicrosoft.VisualStudio.Editor
Microsoft.VisualStudio.Language.IntellisenseMicrosoft.VisualStudio.Language.Intellisense
VisualStudio.Microsoft.VisualStudio.OLE.Interop
VisualStudio. 14.0Microsoft.VisualStudio.Shell.14.0
VisualStudio입니다.Microsoft.VisualStudio.TextManager.Interop
서명 도움말 서명 및 매개 변수 구현Implement Signature Help signatures and parameters
서명 도움말 소스는을 구현 하는 서명을 기반으로 ISignature 하며, 각각은를 구현 하는 매개 변수를 포함 IParameter 합니다.The Signature Help source is based on signatures that implement ISignature, each of which contains parameters that implement IParameter. 전체 구현에서이 정보는 언어 설명서에서 확인할 수 있지만이 예제에서는 서명이 하드 코드 되어 있습니다.In a full implementation, this information would be obtained from the language documentation, but in this example, the signatures are hard-coded.
서명 도움말 서명 및 매개 변수를 구현 하려면To implement the Signature Help signatures and parameters
클래스 파일을 추가하고 이름을
SignatureHelpSource
로 지정합니다.Add a class file and name itSignatureHelpSource
.다음 가져오기를 추가합니다.Add the following 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;
을 구현 하는 라는 클래스를 추가
TestParameter
IParameter 합니다.Add a class namedTestParameter
that implements IParameter.Friend Class TestParameter Implements IParameter
internal class TestParameter : IParameter
모든 속성을 설정 하는 생성자를 추가 합니다.Add a constructor that sets all the properties.
Public Sub New(ByVal documentation As String, ByVal locus As Span, ByVal name As String, ByVal signature As ISignature) Me.privateDocumentation = documentation Me.privateLocus = locus Me.privateName = name Me.privateSignature = signature End Sub
public TestParameter(string documentation, Span locus, string name, ISignature signature) { Documentation = documentation; Locus = locus; Name = name; Signature = signature; }
의 속성을 추가 IParameter 합니다.Add the properties of IParameter.
Private privateDocumentation As String ReadOnly Property Documentation() As String Implements IParameter.Documentation Get Return privateDocumentation End Get End Property Private privateLocus As Span ReadOnly Property Locus() As Span Implements IParameter.Locus Get Return privateLocus End Get End Property Private privateName As String ReadOnly Property Name() As String Implements IParameter.Name Get Return privateName End Get End Property Private privateSignature As ISignature ReadOnly Property Signature() As ISignature Implements IParameter.Signature Get Return privateSignature End Get End Property Private privatePrettyPrintedLocus As Span ReadOnly Property PrettyPrintedLocus() As Span Implements IParameter.PrettyPrintedLocus Get Return privatePrettyPrintedLocus End Get End Property
public string Documentation { get; private set; } public Span Locus { get; private set; } public string Name { get; private set; } public ISignature Signature { get; private set; } public Span PrettyPrintedLocus { get; private set; }
을 구현 하는 라는 클래스를 추가
TestSignature
ISignature 합니다.Add a class namedTestSignature
that implements ISignature.Friend Class TestSignature Implements ISignature
internal class TestSignature : ISignature
일부 전용 필드를 추가 합니다.Add some private fields.
Private m_subjectBuffer As ITextBuffer Private m_currentParameter As IParameter Private m_content As String Private m_documentation As String Friend m_applicableToSpan As ITrackingSpan Friend m_parameters As ReadOnlyCollection(Of IParameter) Private m_printContent As String
private ITextBuffer m_subjectBuffer; private IParameter m_currentParameter; private string m_content; private string m_documentation; private ITrackingSpan m_applicableToSpan; private ReadOnlyCollection<IParameter> m_parameters; private string m_printContent;
필드를 설정 하 고 이벤트를 구독 하는 생성자를 추가 Changed 합니다.Add a constructor that sets the fields and subscribes to the Changed event.
Friend Sub New(ByVal subjectBuffer As ITextBuffer, ByVal content As String, ByVal doc As String, ByVal parameters As ReadOnlyCollection(Of IParameter)) m_subjectBuffer = subjectBuffer m_content = content m_documentation = doc m_parameters = parameters AddHandler m_subjectBuffer.Changed, AddressOf OnSubjectBufferChanged End Sub
internal TestSignature(ITextBuffer subjectBuffer, string content, string doc, ReadOnlyCollection<IParameter> parameters) { m_subjectBuffer = subjectBuffer; m_content = content; m_documentation = doc; m_parameters = parameters; m_subjectBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(OnSubjectBufferChanged); }
이벤트를 선언
CurrentParameterChanged
합니다.Declare aCurrentParameterChanged
event. 이 이벤트는 사용자가 시그니처의 매개 변수 중 하나를 채울 때 발생 합니다.This event is raised when the user fills in one of the parameters in the signature.Public Event CurrentParameterChanged As EventHandler(Of CurrentParameterChangedEventArgs) Implements ISignature.CurrentParameterChanged
public event EventHandler<CurrentParameterChangedEventArgs> CurrentParameterChanged;
속성 CurrentParameter
CurrentParameterChanged
값이 변경 될 때 이벤트가 발생 하도록 속성을 구현 합니다.Implement the CurrentParameter property so that it raises theCurrentParameterChanged
event when the property value is changed.ReadOnly Property CurrentParameter() As IParameter Implements ISignature.CurrentParameter Get Return m_currentParameter End Get End Property
public IParameter CurrentParameter { get { return m_currentParameter; } internal set { if (m_currentParameter != value) { IParameter prevCurrentParameter = m_currentParameter; m_currentParameter = value; this.RaiseCurrentParameterChanged(prevCurrentParameter, m_currentParameter); } } }
이벤트를 발생 시키는 메서드를 추가
CurrentParameterChanged
합니다.Add a method that raises theCurrentParameterChanged
event.Private Sub RaiseCurrentParameterChanged(ByVal prevCurrentParameter As IParameter, ByVal newCurrentParameter As IParameter) Dim tempHandler As EventHandler(Of CurrentParameterChangedEventArgs) = Me.CurrentParameterChangedEvent If tempHandler IsNot Nothing Then tempHandler(Me, New CurrentParameterChangedEventArgs(prevCurrentParameter, newCurrentParameter)) End If End Sub
private void RaiseCurrentParameterChanged(IParameter prevCurrentParameter, IParameter newCurrentParameter) { EventHandler<CurrentParameterChangedEventArgs> tempHandler = this.CurrentParameterChanged; if (tempHandler != null) { tempHandler(this, new CurrentParameterChangedEventArgs(prevCurrentParameter, newCurrentParameter)); } }
의 쉼표 수를 시그니처의 쉼표 수와 비교 하 여 현재 매개 변수를 계산 하는 메서드를 추가 합니다 ApplicableToSpan .Add a method that computes the current parameter by comparing the number of commas in the ApplicableToSpan to the number of commas in the signature.
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]; } }
Changed메서드를 호출 하는 이벤트에 대 한 이벤트 처리기를 추가
ComputeCurrentParameter()
합니다.Add an event handler for the Changed event that calls theComputeCurrentParameter()
method.Friend Sub OnSubjectBufferChanged(ByVal sender As Object, ByVal e As TextContentChangedEventArgs) Me.ComputeCurrentParameter() End Sub
internal void OnSubjectBufferChanged(object sender, TextContentChangedEventArgs e) { this.ComputeCurrentParameter(); }
ApplicableToSpan 속성을 구현합니다.Implement the ApplicableToSpan property. 이 속성에는 ITrackingSpan 서명이 적용 되는 버퍼의 텍스트 범위에 해당 하는이 포함 됩니다.This property holds an ITrackingSpan that corresponds to the span of text in the buffer to which the signature applies.
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; } }
다른 매개 변수를 구현 합니다.Implement the other parameters.
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; } }
서명 도움말 소스 구현Implement the Signature Help source
서명 도움말 원본은 정보를 제공 하는 서명 집합입니다.The Signature Help source is the set of signatures for which you provide information.
서명 도움말 원본을 구현 하려면To implement the Signature Help source
을 구현 하는 라는 클래스를 추가
TestSignatureHelpSource
ISignatureHelpSource 합니다.Add a class namedTestSignatureHelpSource
that implements ISignatureHelpSource.Friend Class TestSignatureHelpSource Implements ISignatureHelpSource
internal class TestSignatureHelpSource : ISignatureHelpSource
텍스트 버퍼에 대 한 참조를 추가 합니다.Add a reference to the text buffer.
Private m_textBuffer As ITextBuffer
private ITextBuffer m_textBuffer;
텍스트 버퍼 및 서명 도움말 소스 공급자를 설정 하는 생성자를 추가 합니다.Add a constructor that sets the text buffer and the Signature Help source provider.
Public Sub New(ByVal textBuffer As ITextBuffer) m_textBuffer = textBuffer End Sub
public TestSignatureHelpSource(ITextBuffer textBuffer) { m_textBuffer = textBuffer; }
AugmentSignatureHelpSession 메서드를 구현합니다.Implement the AugmentSignatureHelpSession method. 이 예제에서는 서명이 하드 코드 되지만 전체 구현에서는 언어 설명서에서이 정보를 얻을 수 있습니다.In this example, the signatures are hard-coded, but in a full implementation you would get this information from the language documentation.
Public Sub AugmentSignatureHelpSession(ByVal session As ISignatureHelpSession, ByVal signatures As IList(Of ISignature)) Implements ISignatureHelpSource.AugmentSignatureHelpSession Dim snapshot As ITextSnapshot = m_textBuffer.CurrentSnapshot Dim position As Integer = session.GetTriggerPoint(m_textBuffer).GetPosition(snapshot) Dim applicableToSpan As ITrackingSpan = m_textBuffer.CurrentSnapshot.CreateTrackingSpan(New Span(position, 0), SpanTrackingMode.EdgeInclusive, 0) signatures.Add(CreateSignature(m_textBuffer, "add(int firstInt, int secondInt)", "Documentation for adding integers.", applicableToSpan)) signatures.Add(CreateSignature(m_textBuffer, "add(double firstDouble, double secondDouble)", "Documentation for adding doubles.", applicableToSpan)) End Sub
public void AugmentSignatureHelpSession(ISignatureHelpSession session, IList<ISignature> signatures) { ITextSnapshot snapshot = m_textBuffer.CurrentSnapshot; int position = session.GetTriggerPoint(m_textBuffer).GetPosition(snapshot); ITrackingSpan applicableToSpan = m_textBuffer.CurrentSnapshot.CreateTrackingSpan( new Span(position, 0), SpanTrackingMode.EdgeInclusive, 0); signatures.Add(CreateSignature(m_textBuffer, "add(int firstInt, int secondInt)", "Documentation for adding integers.", applicableToSpan)); signatures.Add(CreateSignature(m_textBuffer, "add(double firstDouble, double secondDouble)", "Documentation for adding doubles.", applicableToSpan)); }
도우미 메서드는 설명
CreateSignature()
목적 으로만 제공 됩니다.The helper methodCreateSignature()
is provided just for illustration.Private Function CreateSignature(ByVal textBuffer As ITextBuffer, ByVal methodSig As String, ByVal methodDoc As String, ByVal span As ITrackingSpan) As TestSignature Dim sig As New TestSignature(textBuffer, methodSig, methodDoc, Nothing) AddHandler textBuffer.Changed, AddressOf sig.OnSubjectBufferChanged 'find the parameters in the method signature (expect methodname(one, two) Dim pars() As String = methodSig.Split(New Char() {"("c, ","c, ")"c}) Dim paramList As New List(Of IParameter)() Dim locusSearchStart As Integer = 0 For i As Integer = 1 To pars.Length - 1 Dim param As String = pars(i).Trim() If String.IsNullOrEmpty(param) Then Continue For End If 'find where this parameter is located in the method signature Dim locusStart As Integer = methodSig.IndexOf(param, locusSearchStart) If locusStart >= 0 Then Dim locus As New Span(locusStart, param.Length) locusSearchStart = locusStart + param.Length paramList.Add(New TestParameter("Documentation for the parameter.", locus, param, sig)) End If Next i sig.m_Parameters = New ReadOnlyCollection(Of IParameter)(paramList) sig.m_ApplicableToSpan = span sig.ComputeCurrentParameter() Return sig End Function
private TestSignature CreateSignature(ITextBuffer textBuffer, string methodSig, string methodDoc, ITrackingSpan span) { TestSignature sig = new TestSignature(textBuffer, methodSig, methodDoc, null); textBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(sig.OnSubjectBufferChanged); //find the parameters in the method signature (expect methodname(one, two) string[] pars = methodSig.Split(new char[] { '(', ',', ')' }); List<IParameter> paramList = new List<IParameter>(); int locusSearchStart = 0; for (int i = 1; i < pars.Length; i++) { string param = pars[i].Trim(); if (string.IsNullOrEmpty(param)) continue; //find where this parameter is located in the method signature int locusStart = methodSig.IndexOf(param, locusSearchStart); if (locusStart >= 0) { Span locus = new Span(locusStart, param.Length); locusSearchStart = locusStart + param.Length; paramList.Add(new TestParameter("Documentation for the parameter.", locus, param, sig)); } } sig.Parameters = new ReadOnlyCollection<IParameter>(paramList); sig.ApplicableToSpan = span; sig.ComputeCurrentParameter(); return sig; }
GetBestMatch 메서드를 구현합니다.Implement the GetBestMatch method. 이 예제에는 두 개의 매개 변수가 있는 시그니처가 있습니다.In this example, there are just two signatures, each of which has two parameters. 따라서이 메서드는 필요 하지 않습니다.Therefore, this method is not required. 둘 이상의 시그니처 도움말 소스를 사용할 수 있는 완전 한 구현에서는이 메서드를 사용 하 여 우선 순위가 가장 높은 서명 도움말 소스가 일치 하는 시그니처를 제공할 수 있는지 여부를 결정 합니다.In a fuller implementation, in which more than one Signature Help source is available, this method is used to decide whether the highest-priority Signature Help source can supply a matching signature. 사용할 수 없는 경우이 메서드는 null을 반환 하 고, 다음으로 높은 우선 순위 소스가 일치 하는 항목을 제공 하도록 요청 됩니다.If it can't, the method returns null and the next-highest-priority source is asked to supply a match.
Public Function GetBestMatch(ByVal session As ISignatureHelpSession) As ISignature Implements ISignatureHelpSource.GetBestMatch If session.Signatures.Count > 0 Then Dim applicableToSpan As ITrackingSpan = session.Signatures(0).ApplicableToSpan Dim text As String = applicableToSpan.GetText(applicableToSpan.TextBuffer.CurrentSnapshot) If text.Trim().Equals("add") Then 'get only "add" Return session.Signatures(0) End If End If Return Nothing End Function
public ISignature GetBestMatch(ISignatureHelpSession session) { if (session.Signatures.Count > 0) { ITrackingSpan applicableToSpan = session.Signatures[0].ApplicableToSpan; string text = applicableToSpan.GetText(applicableToSpan.TextBuffer.CurrentSnapshot); if (text.Trim().Equals("add")) //get only "add" return session.Signatures[0]; } return null; }
메서드를 구현 합니다
Dispose()
.Implement theDispose()
method: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; } }
서명 도움말 소스 공급자 구현Implement the Signature Help source provider
서명 도움말 소스 공급자는 MEF (Managed Extensibility Framework) 구성 요소 파트를 내보내고 서명 도움말 원본을 인스턴스화하는 역할을 담당 합니다.The Signature Help source provider is responsible for exporting the Managed Extensibility Framework (MEF) component part and for instantiating the Signature Help source.
서명 도움말 소스 공급자를 구현 하려면To implement the Signature Help source provider
을 구현 하는 라는 클래스를 추가 하
TestSignatureHelpSourceProvider
ISignatureHelpSourceProvider 고 NameAttribute , ContentTypeAttribute "Text"의 및 OrderAttribute Before = "default"를 사용 하 여 내보냅니다.Add a class namedTestSignatureHelpSourceProvider
that implements ISignatureHelpSourceProvider, and export it with a NameAttribute, a ContentTypeAttribute of "text", and an OrderAttribute of Before="default".<Export(GetType(ISignatureHelpSourceProvider)), Name("Signature Help source"), Order(Before:="default"), ContentType("text")> Friend Class TestSignatureHelpSourceProvider Implements ISignatureHelpSourceProvider
[Export(typeof(ISignatureHelpSourceProvider))] [Name("Signature Help source")] [Order(Before = "default")] [ContentType("text")] internal class TestSignatureHelpSourceProvider : ISignatureHelpSourceProvider
TryCreateSignatureHelpSource를 인스턴스화하여 구현
TestSignatureHelpSource
합니다.Implement TryCreateSignatureHelpSource by instantiating theTestSignatureHelpSource
.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); }
명령 처리기 구현Implement the command handler
서명 도움말은 일반적으로 여는 괄호 "(" 문자, 닫는 괄호 ")" 문자로 인해 트리거됩니다.Signature Help is typically triggered by an opening parenthesis "(" character and dismissed by a closing parenthesis ")" character. 을 실행 하 여 이러한 키 입력을 처리 하 IOleCommandTarget 고, 알려진 메서드 이름 앞에 여는 괄호 문자를 받을 때 서명 도움말 세션을 트리거하고 닫는 괄호 문자를 받을 때 세션을 닫을 수 있습니다.You can handle these keystrokes by running a IOleCommandTarget so that it triggers a Signature Help session when it receives an opening parenthesis character preceded by a known method name, and dismisses the session when it receives a closing parenthesis character.
명령 처리기를 구현 하려면To implement the command handler
을 구현 하는 라는 클래스를 추가
TestSignatureHelpCommand
IOleCommandTarget 합니다.Add a class namedTestSignatureHelpCommand
that implements IOleCommandTarget.Friend NotInheritable Class TestSignatureHelpCommandHandler Implements IOleCommandTarget
internal sealed class TestSignatureHelpCommandHandler : IOleCommandTarget
명령 처리기를 명령 처리기 IVsTextView 체인에 추가할 수 있는 어댑터에 대 한 전용 필드, 텍스트 뷰, 서명 도움말 브로커 및 세션, a 및 다음을 추가 ITextStructureNavigator IOleCommandTarget 합니다.Add private fields for the IVsTextView adapter (which lets you add the command handler to the chain of command handlers), the text view, the Signature Help broker and session, a ITextStructureNavigator, and the next 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;
생성자를 추가 하 여 이러한 필드를 초기화 하 고 명령 필터 체인에 명령 필터를 추가 합니다.Add a constructor to initialize these fields and to add the command filter to the chain of command filters.
Friend Sub New(ByVal textViewAdapter As IVsTextView, ByVal textView As ITextView, ByVal nav As ITextStructureNavigator, ByVal broker As ISignatureHelpBroker) Me.m_textView = textView Me.m_broker = broker Me.m_navigator = nav 'add this to the filter chain textViewAdapter.AddCommandFilter(Me, m_nextCommandHandler) End Sub
internal TestSignatureHelpCommandHandler(IVsTextView textViewAdapter, ITextView textView, ITextStructureNavigator nav, ISignatureHelpBroker broker) { this.m_textView = textView; this.m_broker = broker; this.m_navigator = nav; //add this to the filter chain textViewAdapter.AddCommandFilter(this, out m_nextCommandHandler); }
메서드를 구현 Exec 하 여 명령 필터에서 알려진 메서드 이름 중 하나 뒤에 여는 괄호 "(" 문자를 받고, 세션이 아직 활성 상태인 동안 닫는 괄호 ")" 문자를 받을 때 세션을 해제할 때 서명 도움말 세션을 트리거합니다.Implement the Exec method to trigger the Signature Help session when the command filter receives an opening parenthesis "(" character after one of the known method names, and to dismiss the session when it receives a closing parenthesis ")" character while the session is still active. 모든 경우에 명령이 전달 됩니다.In every case, the command is forwarded.
Public Function Exec(ByRef pguidCmdGroup As Guid, ByVal nCmdID As UInteger, ByVal nCmdexecopt As UInteger, ByVal pvaIn As IntPtr, ByVal pvaOut As IntPtr) As Integer Implements IOleCommandTarget.Exec Dim typedChar As Char = Char.MinValue If pguidCmdGroup = VSConstants.VSStd2K AndAlso nCmdID = CUInt(VSConstants.VSStd2KCmdID.TYPECHAR) Then typedChar = CChar(ChrW(CUShort(Marshal.GetObjectForNativeVariant(pvaIn)))) If typedChar.Equals("("c) Then 'move the point back so it's in the preceding word Dim point As SnapshotPoint = m_textView.Caret.Position.BufferPosition - 1 Dim extent As TextExtent = m_navigator.GetExtentOfWord(point) Dim word As String = extent.Span.GetText() If word.Equals("add") Then m_session = m_broker.TriggerSignatureHelp(m_textView) End If ElseIf typedChar.Equals(")"c) AndAlso m_session IsNot Nothing Then m_session.Dismiss() m_session = Nothing End If End If Return m_nextCommandHandler.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut) End Function
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { char typedChar = char.MinValue; if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); if (typedChar.Equals('(')) { //move the point back so it's in the preceding word SnapshotPoint point = m_textView.Caret.Position.BufferPosition - 1; TextExtent extent = m_navigator.GetExtentOfWord(point); string word = extent.Span.GetText(); if (word.Equals("add")) m_session = m_broker.TriggerSignatureHelp(m_textView); } else if (typedChar.Equals(')') && m_session != null) { m_session.Dismiss(); m_session = null; } } return m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); }
QueryStatus항상 명령을 전달 하도록 메서드를 구현 합니다.Implement the QueryStatus method so that it always forwards the command.
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); }
서명 도움말 명령 공급자 구현Implement the Signature Help command provider
IVsTextViewCreationListener텍스트 뷰를 만들 때 명령 처리기를 인스턴스화하기 위해를 구현 하 여 서명 도움말 명령을 제공할 수 있습니다.You can provide the Signature Help command by implementing the IVsTextViewCreationListener to instantiate the command handler when the text view is created.
서명 도움말 명령 공급자를 구현 하려면To implement the Signature Help command provider
을 구현 하는 라는 클래스를 추가 하
TestSignatureHelpController
IVsTextViewCreationListener 고, 및를 사용 하 여 내보냅니다 NameAttribute ContentTypeAttribute TextViewRoleAttribute .Add a class namedTestSignatureHelpController
that implements IVsTextViewCreationListener and export it with the NameAttribute, ContentTypeAttribute, and TextViewRoleAttribute.<Export(GetType(IVsTextViewCreationListener)), Name("Signature Help controller"), TextViewRole(PredefinedTextViewRoles.Editable), ContentType("text")> Friend Class TestSignatureHelpCommandProvider Implements IVsTextViewCreationListener
[Export(typeof(IVsTextViewCreationListener))] [Name("Signature Help controller")] [TextViewRole(PredefinedTextViewRoles.Editable)] [ContentType("text")] internal class TestSignatureHelpCommandProvider : IVsTextViewCreationListener
( IVsEditorAdaptersFactoryService 개체를 가져오는 데 사용 됨 ITextView IVsTextView ), ITextStructureNavigatorSelectorService (현재 단어를 찾는 데 사용 됨) 및 ISignatureHelpBroker (서명 도움말 세션을 트리거하기 위해)을 가져옵니다.Import the IVsEditorAdaptersFactoryService (used to get the ITextView, given the IVsTextView object), the ITextStructureNavigatorSelectorService (used to find the current word), and the ISignatureHelpBroker (to trigger the Signature Help session).
<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;
VsTextViewCreated를 인스턴스화하여 메서드를 구현 합니다
TestSignatureCommandHandler
.Implement the VsTextViewCreated method by instantiating theTestSignatureCommandHandler
.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)); }
코드 빌드 및 테스트Build and Test the Code
이 코드를 테스트 하려면 서명 Helptest 솔루션을 빌드하고 실험적 인스턴스에서 실행 합니다.To test this code, build the SignatureHelpTest solution and run it in the experimental instance.
서명 도움말 테스트 솔루션을 빌드 및 테스트 하려면To build and test the SignatureHelpTest solution
솔루션을 빌드합니다.Build the solution.
디버거에서이 프로젝트를 실행 하면 Visual Studio의 두 번째 인스턴스가 시작 됩니다.When you run this project in the debugger, a second instance of Visual Studio is started.
텍스트 파일을 만들고 단어 "추가"와 여는 괄호를 포함 하는 텍스트를 입력 합니다.Create a text file and type some text that includes the word "add" plus an opening parenthesis.
여는 괄호를 입력 한 후에는 메서드에 대 한 두 서명 목록을 표시 하는 도구 설명이 표시 됩니다
add()
.After you type the opening parenthesis, you should see a tooltip that displays a list of the two signatures for theadd()
method.