İzlenecek yol: İmza Yardımını Görüntüleme
İmza Yardımı (Parametre Bilgisi olarak da bilinir), kullanıcı parametre listesi başlangıç karakterini (genellikle açma parantezi) yazdığınızda araç ipucunda bir yöntemin imzasını görüntüler. Parametre ve parametre ayırıcısı (genellikle virgül) yazıldığında, araç ipucu sonraki parametreyi kalın olarak gösterecek şekilde güncelleştirilir. İmza Yardımı'nı aşağıdaki yollarla tanımlayabilirsiniz: dil hizmeti bağlamında, kendi dosya adı uzantınızı ve içerik türünüzü tanımlayın ve yalnızca bu tür için İmza Yardımı'nı görüntüleyin veya var olan bir içerik türü için İmza Yardımı'nı (örneğin, "metin") görüntüleyin. Bu kılavuz, "metin" içerik türü için İmza Yardımı'nın nasıl görüntüleneceğini gösterir.
İmza Yardımı genellikle "(" (parantez açma) gibi belirli bir karakter yazılarak tetiklenerek tetikler ve başka bir karakter( örneğin, ")" (parantez kapatılarak) kapatılır. Karakter yazarak tetiklenen IntelliSense özellikleri, tuş vuruşları ( IOleCommandTarget arabirim) için bir komut işleyicisi ve arabirimi uygulayan IVsTextViewCreationListener bir işleyici sağlayıcısı kullanılarak uygulanabilir. İmza Yardımı'na katılan imzaların listesi olan İmza Yardımı kaynağını oluşturmak için arabirimi ve arabirimi çalıştıran bir kaynak sağlayıcısı uygulayın ISignatureHelpSource ISignatureHelpSourceProvider . Sağlayıcılar Yönetilen Genişletilebilirlik Çerçevesi (MEF) bileşen parçalarıdır ve kaynak ve denetleyici sınıflarını dışarı aktarmak ve hizmet ve aracıları içeri aktarmakla sorumludur; örneğin, ITextStructureNavigatorSelectorServicemetin arabelleğinde gezinmenizi sağlayan ve İmza Yardımı oturumunu ISignatureHelpBrokertetikleyen .
Bu kılavuzda, sabit kodlanmış bir tanımlayıcı kümesi için İmza Yardımı'nın nasıl ayarlanacağı gösterilmektedir. Tam uygulamalarda, bu içeriğin sağlanmasından dil sorumludur.
MEF projesi oluşturma
MEF projesi oluşturmak için
C# VSIX projesi oluşturun. (Yeni Proje iletişim kutusu, Visual C# / Genişletilebilirlik'i ve ardından VSIX Projesi'ni seçin.) Çözümü
SignatureHelpTest
olarak adlandırın.Projeye bir Düzenleyici Sınıflandırıcısı öğesi şablonu ekleyin. Daha fazla bilgi için bkz . Düzenleyici öğesi şablonuyla uzantı oluşturma.
Varolan sınıf dosyalarını silin.
Projeye aşağıdaki başvuruları ekleyin ve CopyLocal öğesinin olarak
false
ayarlandığından emin olun:Microsoft.VisualStudio.Editor
Microsoft.VisualStudio.Language.Intellisense
Microsoft.visualstudio.ole
Microsoft.VisualStudio.Shell.14.0
Microsoft.VisualStudio.TextManager.Interop
İmza Yardımı imzalarını ve parametrelerini uygulama
İmza Yardımı kaynağı, uygulamasını uygulayan ISignatureimzaları temel alır ve bunların her biri uygulayan IParameterparametreleri içerir. Tam bir uygulamada, bu bilgiler dil belgelerinden alınabilir, ancak bu örnekte imzalar sabit kodlanmıştır.
İmza Yardımı imzalarını ve parametrelerini uygulamak için
Bir sınıf dosyası ekleyin ve adını verin
SignatureHelpSource
.Aşağıdaki içeri aktarmaları ekleyin.
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;
uygulayan IParameteradlı
TestParameter
bir sınıf ekleyin.Tüm özellikleri ayarlayan bir oluşturucu ekleyin.
özelliklerini IParameterekleyin.
uygulayan ISignatureadlı
TestSignature
bir sınıf ekleyin.Bazı özel alanlar ekleyin.
Alanları ayarlayan ve olaya abone Changed olan bir oluşturucu ekleyin.
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); }
Bir
CurrentParameterChanged
olay bildirin. Bu olay, kullanıcı imzadaki parametrelerden birini doldurduğunda oluşturulur.CurrentParameter özellik değeri değiştirildiğinde olayı tetiklemesi
CurrentParameterChanged
için özelliğini uygulayın.Olayı tetikleyen
CurrentParameterChanged
bir yöntem ekleyin.private void RaiseCurrentParameterChanged(IParameter prevCurrentParameter, IParameter newCurrentParameter) { EventHandler<CurrentParameterChangedEventArgs> tempHandler = this.CurrentParameterChanged; if (tempHandler != null) { tempHandler(this, new CurrentParameterChangedEventArgs(prevCurrentParameter, newCurrentParameter)); } }
içindeki virgül ApplicableToSpan sayısını imzadaki virgül sayısıyla karşılaştırarak geçerli parametreyi hesaplayan bir yöntem ekleyin.
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]; } }
yöntemini çağıran olay için Changed bir olay işleyicisi
ComputeCurrentParameter()
ekleyin.ApplicableToSpan özelliğini uygulayın. Bu özellik, imzanın uygulandığı arabellekteki metnin yayılmasına karşılık gelen bir ITrackingSpan değeri tutar.
Diğer parametreleri uygulayın.
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; } }
İmza Yardımı kaynağını uygulama
İmza Yardımı kaynağı, bilgi sağladığınız imza kümesidir.
İmza Yardımı kaynağını uygulamak için
uygulayan ISignatureHelpSourceadlı
TestSignatureHelpSource
bir sınıf ekleyin.Metin arabelleğine bir başvuru ekleyin.
Metin arabelleği ve İmza Yardımı kaynak sağlayıcısını ayarlayan bir oluşturucu ekleyin.
AugmentSignatureHelpSession yöntemini uygulayın. Bu örnekte imzalar sabit kodlanmıştır, ancak tam bir uygulamada bu bilgileri dil belgelerinden alabilirsiniz.
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)); }
Yardımcı yöntemi
CreateSignature()
yalnızca çizim için sağlanır.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 yöntemini uygulayın. Bu örnekte, her biri iki parametreye sahip olan yalnızca iki imza vardır. Bu nedenle, bu yöntem gerekli değildir. Birden fazla İmza Yardımı kaynağının kullanılabildiği daha kapsamlı bir uygulamada, en yüksek öncelikli İmza Yardımı kaynağının eşleşen bir imza sağlayıp sağlayamayacağına karar vermek için bu yöntem kullanılır. Bunu yapamazsa, yöntemi null döndürür ve sonraki en yüksek öncelikli kaynağın bir eşleşme sağlaması istenir.
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()
Yöntemini uygulayın:
İmza Yardımı kaynak sağlayıcısını uygulama
İmza Yardımı kaynak sağlayıcısı, Yönetilen Genişletilebilirlik Çerçevesi (MEF) bileşeni bölümünü dışarı aktarmak ve İmza Yardımı kaynağının örneğini başlatmakla sorumludur.
İmza Yardımı kaynak sağlayıcısını uygulamak için
uygulayan ISignatureHelpSourceProvideradlı
TestSignatureHelpSourceProvider
bir sınıf ekleyin ve bunu bir NameAttribute, ContentTypeAttribute bir "metin" ve BeforeOrderAttribute="default" ile dışarı aktarın.örneğini ekleyerek
TestSignatureHelpSource
uygulayınTryCreateSignatureHelpSource.
Komut işleyicisini uygulama
İmza Yardımı genellikle bir açma parantezi "(" karakteriyle tetiklenerek ve kapatma parantezi ")" karakteriyle kapatılır. Bu tuş vuruşlarını, bilinen bir yöntem adından önce bir açma parantezi karakteri aldığında bir İmza Yardımı oturumunu tetikleyecek şekilde çalıştırarak IOleCommandTarget ve kapatma parantezi karakteri aldığında oturumu kapatarak işleyebilirsiniz.
Komut işleyicisini uygulamak için
uygulayan IOleCommandTargetadlı
TestSignatureHelpCommand
bir sınıf ekleyin.Bağdaştırıcı için IVsTextView özel alanlar ekleyin (komut işleyicisini komut işleyicileri zincirine eklemenize olanak tanır), metin görünümü, İmza Yardımı aracısı ve oturumu, bir ITextStructureNavigatorve sonraki IOleCommandTarget.
Bu alanları başlatmak ve komut filtresini komut filtreleri zincirine eklemek için bir oluşturucu ekleyin.
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 Komut filtresi bilinen yöntem adlarından birinin sonunda bir açma parantezi "(" karakter) aldığında İmza Yardımı oturumunu tetikleme yöntemini uygulayın ve oturum hala etkin durumdayken kapatma parantezi "" karakterini aldığında oturumu kapatın. Her durumda, komut iletilir.
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 komutunu her zaman iletebilmesi için yöntemini uygulayın.
İmza Yardımı komut sağlayıcısını uygulama
Metin görünümü oluşturulduğunda komut işleyicisinin örneğini oluşturmak için komutunu uygulayarak IVsTextViewCreationListener İmza Yardımı komutunu sağlayabilirsiniz.
İmza Yardımı komut sağlayıcısını uygulamak için
, ve TextViewRoleAttributeile NameAttributeContentTypeAttributeuygulayan IVsTextViewCreationListener ve dışarı aktaran adlı
TestSignatureHelpController
bir sınıf ekleyin.IVsEditorAdaptersFactoryService öğesini (nesnesine göre IVsTextView değerini almak ITextViewiçin kullanılır), ITextStructureNavigatorSelectorService (geçerli sözcüğü bulmak için kullanılır) ve ISignatureHelpBroker (İmza Yardımı oturumunu tetikleme amacıyla) içeri aktarın.
örneğini VsTextViewCreated ekleyerek
TestSignatureCommandHandler
yöntemini uygulayın.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)); }
Kodu Derleme ve Test Etme
Bu kodu test etmek için SignatureHelpTest çözümünü derleyin ve deneysel örnekte çalıştırın.
SignatureHelpTest çözümünü derlemek ve test etmek için
Çözümü oluşturun.
Bu projeyi hata ayıklayıcıda çalıştırdığınızda, Visual Studio'nun ikinci bir örneği başlatılır.
Bir metin dosyası oluşturun ve "ekle" sözcüğünün yanı sıra bir açılış ayracı içeren bir metin yazın.
Açma parantezini yazdıktan sonra, yöntem için
add()
iki imzanın listesini görüntüleyen bir araç ipucu görmeniz gerekir.