Tutorial: Mostrar información sobre herramientas de QuickInfo
QuickInfo es una característica de IntelliSense que muestra las firmas y descripciones del método cuando un usuario mueve el puntero sobre un nombre de método. Puede implementar características basadas en lenguaje, como QuickInfo, definiendo los identificadores para los que desea proporcionar descripciones de QuickInfo y, a continuación, creando una información sobre herramientas en la que mostrar el contenido. Puede definir QuickInfo en el contexto de un servicio de lenguaje, o puede definir su propia extensión de nombre de archivo y tipo de contenido y mostrar QuickInfo solo para ese tipo, o puede mostrar QuickInfo para un tipo de contenido existente (como "texto"). En este tutorial se muestra cómo mostrar QuickInfo para el tipo de contenido "text".
El ejemplo QuickInfo de este tutorial muestra la información sobre herramientas cuando un usuario mueve el puntero sobre un nombre de método. Este diseño requiere que implemente estas cuatro interfaces:
interfaz de origen
interfaz del proveedor de origen
interfaz del controlador
interfaz del proveedor de controlador
Los proveedores de controladores y de origen son componentes de Managed Extensibility Framework (MEF) y son responsables de exportar las clases de origen y controlador e importar servicios y agentes como ITextBufferFactoryService, que crea el búfer de texto de información sobre herramientas y , IQuickInfoBrokerque desencadena la sesión quickInfo.
En este ejemplo, el origen quickInfo usa una lista codificada de forma rígida de nombres y descripciones de métodos, pero en implementaciones completas, el servicio de lenguaje y la documentación del lenguaje son responsables de proporcionar ese contenido.
Creación de un proyecto MEF
Para crear un nuevo proyecto de MEF
Cree un proyecto VSIX de C#. (En Cuadro de diálogo Nuevo proyecto , seleccione Visual C# / Extensibilidad y, después , Proyecto VSIX). Asigne un nombre a la solución
QuickInfoTest
.Agregue una plantilla de elemento clasificador del editor al proyecto. Para obtener más información, vea Creación de una extensión con una plantilla de elemento de editor.
Elimine los archivos de clase existentes.
Implementación del origen quickInfo
El origen quickInfo es responsable de recopilar el conjunto de identificadores y sus descripciones y agregar el contenido al búfer de texto de información sobre herramientas cuando se encuentra uno de los identificadores. En este ejemplo, los identificadores y sus descripciones solo se agregan en el constructor de origen.
Para implementar el origen de QuickInfo
Agregue un archivo de clase y asígnele el nombre
TestQuickInfoSource
.Agregue una referencia a Microsoft.VisualStudio.Language.IntelliSense.
Agregue las importaciones siguientes.
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel.Composition; using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Text.Tagging; using Microsoft.VisualStudio.Utilities;
Declare una clase que implemente IQuickInfoSourcey asígne el
TestQuickInfoSource
nombre .Agregue campos para el proveedor de origen QuickInfo, el búfer de texto y un conjunto de nombres de método y firmas de método. En este ejemplo, los nombres de método y las firmas se inicializan en el
TestQuickInfoSource
constructor.Agregue un constructor que establezca el proveedor de origen QuickInfo y el búfer de texto, y rellene el conjunto de nombres de método y las firmas y descripciones del método.
public TestQuickInfoSource(TestQuickInfoSourceProvider provider, ITextBuffer subjectBuffer) { m_provider = provider; m_subjectBuffer = subjectBuffer; //these are the method names and their descriptions m_dictionary = new Dictionary<string, string>(); m_dictionary.Add("add", "int add(int firstInt, int secondInt)\nAdds one integer to another."); m_dictionary.Add("subtract", "int subtract(int firstInt, int secondInt)\nSubtracts one integer from another."); m_dictionary.Add("multiply", "int multiply(int firstInt, int secondInt)\nMultiplies one integer by another."); m_dictionary.Add("divide", "int divide(int firstInt, int secondInt)\nDivides one integer by another."); }
Implemente el método AugmentQuickInfoSession. En este ejemplo, el método busca la palabra actual o la palabra anterior si el cursor está al final de una línea o un búfer de texto. Si la palabra es uno de los nombres de método, la descripción de ese nombre de método se agrega al contenido quickInfo.
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { // Map the trigger point down to our buffer. SnapshotPoint? subjectTriggerPoint = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { applicableToSpan = null; return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0); //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); string searchText = extent.Span.GetText(); foreach (string key in m_dictionary.Keys) { int foundIndex = searchText.IndexOf(key, StringComparison.CurrentCultureIgnoreCase); if (foundIndex > -1) { applicableToSpan = currentSnapshot.CreateTrackingSpan ( //querySpan.Start.Add(foundIndex).Position, 9, SpanTrackingMode.EdgeInclusive extent.Span.Start + foundIndex, key.Length, SpanTrackingMode.EdgeInclusive ); string value; m_dictionary.TryGetValue(key, out value); if (value != null) qiContent.Add(value); else qiContent.Add(""); return; } } applicableToSpan = null; }
También debe implementar un método Dispose(), ya que IQuickInfoSource implementa IDisposable:
Implementación de un proveedor de origen quickInfo
El proveedor del origen QuickInfo sirve principalmente para exportarse como parte de componente MEF y crear instancias del origen quickInfo. Dado que es una parte de componente MEF, puede importar otras partes de componentes MEF.
Para implementar un proveedor de origen quickInfo
Declare un proveedor de origen quickInfo denominado
TestQuickInfoSourceProvider
que implementa IQuickInfoSourceProvidery lo exporte con un NameAttribute de "Origen de quickInfo de información sobre herramientas", un OrderAttribute de Before="default" y un ContentTypeAttribute de "text".Importe dos servicios de editor y ITextStructureNavigatorSelectorService ITextBufferFactoryService, como propiedades de
TestQuickInfoSourceProvider
.Implemente TryCreateQuickInfoSource para devolver un nuevo
TestQuickInfoSource
.
Implementación de un controlador QuickInfo
Los controladores QuickInfo determinan cuándo se muestra QuickInfo. En este ejemplo, QuickInfo aparece cuando el puntero está sobre una palabra que corresponde a uno de los nombres de método. El controlador QuickInfo implementa un controlador de eventos de puntero del mouse que desencadena una sesión de QuickInfo.
Para implementar un controlador QuickInfo
Declare una clase que implemente IIntellisenseControllery asígne el
TestQuickInfoController
nombre .Agregue campos privados para la vista de texto, los búferes de texto representados en la vista de texto, la sesión QuickInfo y el proveedor del controlador QuickInfo.
Agregue un constructor que establezca los campos y agregue el controlador de eventos de puntero del mouse.
Agregue el controlador de eventos de puntero del mouse que desencadena la sesión QuickInfo.
private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e) { //find the mouse position by mapping down to the subject buffer SnapshotPoint? point = m_textView.BufferGraph.MapDownToFirstMatch (new SnapshotPoint(m_textView.TextSnapshot, e.Position), PointTrackingMode.Positive, snapshot => m_subjectBuffers.Contains(snapshot.TextBuffer), PositionAffinity.Predecessor); if (point != null) { ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position, PointTrackingMode.Positive); if (!m_provider.QuickInfoBroker.IsQuickInfoActive(m_textView)) { m_session = m_provider.QuickInfoBroker.TriggerQuickInfo(m_textView, triggerPoint, true); } } }
Implemente el Detach método para que quite el controlador de eventos del mouse cuando el controlador se desasocie de la vista de texto.
Implemente el ConnectSubjectBuffer método y el DisconnectSubjectBuffer método como métodos vacíos para este ejemplo.
Implementación del proveedor del controlador QuickInfo
El proveedor del controlador QuickInfo sirve principalmente para exportarse como parte de componente MEF y crear instancias del controlador QuickInfo. Dado que es una parte de componente MEF, puede importar otras partes de componentes MEF.
Para implementar el proveedor del controlador QuickInfo
Declare una clase denominada
TestQuickInfoControllerProvider
que implementa IIntellisenseControllerProvidery expórtela con un NameAttribute elemento de "Controlador quickInfo de información sobre herramientas" y un ContentTypeAttribute de "texto":Importe el IQuickInfoBroker como una propiedad.
Implemente el método mediante la TryCreateIntellisenseController creación de instancias del controlador QuickInfo.
Compilación y prueba del código
Para probar este código, compile la solución QuickInfoTest y ejecútela en la instancia experimental.
Para compilar y probar la solución QuickInfoTest
Compile la solución.
Al ejecutar este proyecto en el depurador, se inicia una segunda instancia de Visual Studio.
Cree un archivo de texto y escriba algún texto que incluya las palabras "agregar" y "restar".
Mueva el puntero sobre una de las apariciones de "add". Se debe mostrar la firma y la descripción del
add
método.