Punti di estensione del servizio di linguaggio e dell'editor
L'editor fornisce punti di estensione che è possibile estendere come parti del componente MEF (Managed Extensibility Framework), inclusa la maggior parte delle funzionalità del servizio di linguaggio. Queste sono le categorie principali di punti di estensione:
Tipi di contenuto
Tipi di classificazione e formati di classificazione
Margini e barre di scorrimento
Tag
Ornamenti
Processori del mouse
Eliminare i gestori
Opzioni
IntelliSense
Estendere i tipi di contenuto
I tipi di contenuto sono le definizioni dei tipi di testo gestiti dall'editor, ad esempio "text", "code" o "CSharp". Per definire un nuovo tipo di contenuto, dichiarare una variabile del tipo ContentTypeDefinition e assegnare al nuovo tipo di contenuto un nome univoco. Per registrare il tipo di contenuto con l'editor, esportarlo insieme agli attributi seguenti:
NameAttribute è il nome del tipo di contenuto.
BaseDefinitionAttribute è il nome del tipo di contenuto da cui deriva questo tipo di contenuto. Un tipo di contenuto può ereditare da più tipi di contenuto.
Poiché la ContentTypeDefinition classe è sealed, è possibile esportarla senza alcun parametro di tipo.
Nell'esempio seguente vengono illustrati gli attributi di esportazione in una definizione del tipo di contenuto.
[Export]
[Name("test")]
[BaseDefinition("code")]
[BaseDefinition("projection")]
internal static ContentTypeDefinition TestContentTypeDefinition;
I tipi di contenuto possono essere basati su zero o più tipi di contenuto preesistenti. Questi sono i tipi predefiniti:
Any: tipo di contenuto di base. Padre di tutti gli altri tipi di contenuto.
Testo: tipo di base per il contenuto non di proiezione. Eredita da "any".
Testo non crittografato: per il testo non codificato. Eredita da "text".
Codice: per il codice di tutti i tipi. Eredita da "text".
Inert: esclude il testo da qualsiasi tipo di gestione. Il testo di questo tipo di contenuto non avrà mai alcuna estensione applicata.
Proiezione: per il contenuto dei buffer di proiezione. Eredita da "any".
IntelliSense: per il contenuto di IntelliSense. Eredita da "text".
Sighelp: guida alla firma. Eredita da "intellisense".
Sighelp-doc: documentazione della Guida alla firma. Eredita da "intellisense".
Questi sono alcuni dei tipi di contenuto definiti da Visual Studio e alcuni dei linguaggi ospitati in Visual Studio:
Di base
C/C++
ConsoleOutput
CSharp
CSS
ENC
FindResults
F#
HTML
JScript
XAML
XML
Per individuare l'elenco dei tipi di contenuto disponibili, importare , IContentTypeRegistryServiceche gestisce la raccolta di tipi di contenuto per l'editor. Il codice seguente importa questo servizio come proprietà.
[Import]
internal IContentTypeRegistryService ContentTypeRegistryService { get; set; }
Per associare un tipo di contenuto a un'estensione di file, usare FileExtensionToContentTypeDefinition.
Nota
In Visual Studio le estensioni dei nomi di file vengono registrate usando in ProvideLanguageExtensionAttribute un pacchetto del servizio di linguaggio. Associa FileExtensionToContentTypeDefinition un tipo di contenuto MEF a un'estensione di file registrata in questo modo.
Per esportare l'estensione del nome file nella definizione del tipo di contenuto, è necessario includere gli attributi seguenti:
FileExtensionAttribute: specifica l'estensione del nome file.
ContentTypeAttribute: specifica il tipo di contenuto.
Poiché la FileExtensionToContentTypeDefinition classe è sealed, è possibile esportarla senza alcun parametro di tipo.
L'esempio seguente mostra gli attributi di esportazione in un'estensione di file in una definizione del tipo di contenuto.
[Export]
[FileExtension(".test")]
[ContentType("test")]
internal static FileExtensionToContentTypeDefinition TestFileExtensionDefinition;
IFileExtensionRegistryService Gestisce le associazioni tra le estensioni di file e i tipi di contenuto.
Estendere i tipi di classificazione e i formati di classificazione
È possibile usare i tipi di classificazione per definire i tipi di testo per cui si desidera fornire una gestione diversa, ad esempio colorando il testo "parola chiave" blu e il testo "commento" verde. Definire un nuovo tipo di classificazione dichiarando una variabile di tipo ClassificationTypeDefinition e assegnando un nome univoco.
Per registrare il tipo di classificazione con l'editor, esportarlo insieme agli attributi seguenti:
NameAttribute: nome del tipo di classificazione.
BaseDefinitionAttribute: nome del tipo di classificazione da cui eredita questo tipo di classificazione. Tutti i tipi di classificazione ereditano da "text" e un tipo di classificazione può ereditare da più altri tipi di classificazione.
Poiché la ClassificationTypeDefinition classe è sealed, è possibile esportarla senza alcun parametro di tipo.
Nell'esempio seguente vengono illustrati gli attributi di esportazione in una definizione di tipo di classificazione.
[Export]
[Name("csharp.test")]
[BaseDefinition("test")]
internal static ClassificationTypeDefinition CSharpTestDefinition;
IStandardClassificationService fornisce l'accesso alle classificazioni standard. I tipi di classificazione predefiniti includono:
"text"
"linguaggio naturale" (deriva da "text")
"linguaggio formale" (deriva da "text")
"string" (deriva da "literal")
"character" (deriva da "literal")
"numerico" (deriva da "literal")
Un set di tipi di errore diversi eredita da ErrorTypeDefinition. Includono i tipi di errore seguenti:
"errore di sintassi"
"errore del compilatore"
"altro errore"
"warning"
Per individuare l'elenco dei tipi di classificazione disponibili, importare , IClassificationTypeRegistryServiceche gestisce la raccolta di tipi di classificazione per l'editor. Il codice seguente importa questo servizio come proprietà.
[Import]
internal IClassificationTypeRegistryService ClassificationTypeRegistryService { get; set; }
È possibile definire una definizione di formato di classificazione per il nuovo tipo di classificazione. Derivare una classe da ClassificationFormatDefinition ed esportarla con il tipo EditorFormatDefinition, insieme agli attributi seguenti:
NameAttribute: nome del formato.
DisplayNameAttribute: nome visualizzato del formato.
UserVisibleAttribute: specifica se il formato viene visualizzato nella pagina Tipi di carattere e colori della finestra di dialogo Opzioni .
OrderAttribute: priorità del formato. I valori validi provengono da Priority.
ClassificationTypeAttribute: nome del tipo di classificazione a cui viene eseguito il mapping di questo formato.
L'esempio seguente mostra gli attributi di esportazione in una definizione di formato di classificazione.
[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = "test")]
[Name("test")]
[DisplayName("Test")]
[UserVisible(true)]
[Order(After = Priority.Default, Before = Priority.High)]
internal sealed class TestFormat : ClassificationFormatDefinition
Per individuare l'elenco dei formati disponibili, importare , IEditorFormatMapServiceche gestisce la raccolta di formati per l'editor. Il codice seguente importa questo servizio come proprietà.
[Import]
internal IEditorFormatMapService FormatMapService { get; set; }
Estendere i margini e le barre di scorrimento
Margini e barre di scorrimento sono gli elementi di visualizzazione principali dell'editor oltre alla visualizzazione testo stessa. È possibile specificare un numero qualsiasi di margini oltre ai margini standard visualizzati intorno alla visualizzazione testo.
Implementare un'interfaccia IWpfTextViewMargin per definire un margine. È inoltre necessario implementare l'interfaccia IWpfTextViewMarginProvider per creare il margine.
Per registrare il provider di margini con l'editor, è necessario esportare il provider insieme agli attributi seguenti:
NameAttribute: nome del margine.
OrderAttribute: l'ordine in cui viene visualizzato il margine, rispetto agli altri margini.
Questi sono i margini predefiniti:
"Barra di scorrimento orizzontale wpf"
"Barra di scorrimento verticale wpf"
"Margine numero riga wpf"
I margini orizzontali con un attributo order di
After="Wpf Horizontal Scrollbar"
vengono visualizzati sotto il margine predefinito e i margini orizzontali con un attributo order diBefore ="Wpf Horizontal Scrollbar"
vengono visualizzati sopra il margine predefinito. I margini verticali destro con un attributo order diAfter="Wpf Vertical Scrollbar"
vengono visualizzati a destra della barra di scorrimento. I margini verticali sinistro con un attributo order di appaiono a sinistra del margine del numero diAfter="Wpf Line Number Margin"
riga (se visibile).
MarginContainerAttribute: tipo di margine (sinistro, destro, superiore o inferiore).
ContentTypeAttribute: tipo di contenuto (ad esempio, "text" o "code") per cui il margine è valido.
Nell'esempio seguente vengono illustrati gli attributi di esportazione in un provider di margini per un margine visualizzato a destra del margine del numero di riga.
[Export(typeof(IWpfTextViewMarginProvider))]
[Name("TestMargin")]
[Order(Before = "Wpf Line Number Margin")]
[MarginContainer(PredefinedMarginNames.Left)]
[ContentType("text")]
Estendere i tag
I tag sono un modo per associare i dati a diversi tipi di testo. In molti casi, i dati associati vengono visualizzati come effetto visivo, ma non tutti i tag hanno una presentazione visiva. È possibile definire il proprio tipo di tag implementando ITag. È inoltre necessario implementare ITagger<T> per specificare i tag per un determinato set di intervalli di testo e un oggetto ITaggerProvider per fornire il tagger. È necessario esportare il provider di tagger insieme agli attributi seguenti:
ContentTypeAttribute: tipo di contenuto (ad esempio, "text" o "code") per cui il tag è valido.
TagTypeAttribute: tipo di tag.
L'esempio seguente mostra gli attributi di esportazione in un provider di tagger.
<CodeContentPlaceHolder>8 I tipi di tag seguenti sono incorporati:
ClassificationTag: associato a un oggetto IClassificationType.
ErrorTag: associato ai tipi di errore.
TextMarkerTag: associato a una decorazione.
Nota
Per un esempio di TextMarkerTag, vedere la definizione HighlightWordTag in Procedura dettagliata: Evidenziazione del testo.
OutliningRegionTag: associato alle aree che possono essere espanse o compresse in struttura.
SpaceNegotiatingAdornmentTag: definisce lo spazio occupato da un elemento decorativo in una visualizzazione di testo. Per altre informazioni sugli strumenti di negoziazione dello spazio, vedere la sezione seguente.
IntraTextAdornmentTag: fornisce spaziatura e ridimensionamento automatici per la decorazione.
Per trovare e usare tag per buffer e visualizzazioni, importare o IViewTagAggregatorFactoryService IBufferTagAggregatorFactoryService, che forniscono un ITagAggregator<T> oggetto del tipo richiesto. Il codice seguente importa questo servizio come proprietà.
[Import]
internal IViewTagAggregatorFactoryService ViewTagAggregatorFactoryService { get; set; }
Tag e MarkerFormatDefinitions
È possibile estendere la MarkerFormatDefinition classe per definire l'aspetto di un tag. È necessario esportare la classe (come EditorFormatDefinition)con gli attributi seguenti:
NameAttribute: nome utilizzato per fare riferimento a questo formato
UserVisibleAttribute: in questo modo il formato viene visualizzato nell'interfaccia utente
Nel costruttore si definiscono il nome visualizzato e l'aspetto del tag. BackgroundColor definisce il colore di riempimento e ForegroundColor definisce il colore del bordo. DisplayName è il nome localizzabile della definizione di formato.
Di seguito è riportato un esempio di definizione di formato:
[Export(typeof(EditorFormatDefinition))]
[Name("MarkerFormatDefinition/HighlightWordFormatDefinition")]
[UserVisible(true)]
internal class HighlightWordFormatDefinition : MarkerFormatDefinition
{
public HighlightWordFormatDefinition()
{
this.BackgroundColor = Colors.LightBlue;
this.ForegroundColor = Colors.DarkBlue;
this.DisplayName = "Highlight Word";
this.ZOrder = 5;
}
}
Per applicare questa definizione di formato a un tag, fare riferimento al nome impostato nell'attributo name della classe (non il nome visualizzato).
Nota
Per un esempio di MarkerFormatDefinition, vedere la classe HighlightWordFormatDefinition in Procedura dettagliata: Evidenziazione del testo.
Estendere le decorazioni
Gli oggetti decorativi definiscono gli effetti visivi che possono essere aggiunti al testo visualizzato in una visualizzazione testo o alla visualizzazione testo stessa. È possibile definire la propria decorazione come qualsiasi tipo di UIElement.
Nella classe di adornamento è necessario dichiarare un oggetto AdornmentLayerDefinition. Per registrare il livello di adornamento, esportarlo insieme agli attributi seguenti:
NameAttribute: nome della decorazione.
OrderAttribute: l'ordinamento della decorazione rispetto ad altri livelli di adornamento. La classe PredefinedAdornmentLayers definisce quattro livelli predefiniti: Selection, Outlining, Caret e Text.
L'esempio seguente mostra gli attributi di esportazione in una definizione del livello di adornamento.
[Export]
[Name("TestEmbeddedAdornment")]
[Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
internal AdornmentLayerDefinition testLayerDefinition;
È necessario creare una seconda classe che implementa IWpfTextViewCreationListener e gestisce il relativo TextViewCreated evento creando un'istanza dello strumento decorativo. È necessario esportare questa classe insieme agli attributi seguenti:
ContentTypeAttribute: tipo di contenuto (ad esempio, "text" o "code") per cui l'elemento decorativo è valido.
TextViewRoleAttribute: tipo di visualizzazione testo per cui questa struttura è valida. La classe PredefinedTextViewRoles ha il set di ruoli di visualizzazione testo predefiniti. Ad esempio, Document viene usato principalmente per le visualizzazioni di testo dei file. Interactive viene usato per le visualizzazioni di testo che un utente può modificare o spostarsi usando un mouse e una tastiera. Esempi di Interactive visualizzazioni sono la visualizzazione testo dell'editor e la finestra Output .
Nell'esempio seguente vengono illustrati gli attributi di esportazione nel provider di strumenti decorativi.
[Export(typeof(IWpfTextViewCreationListener))]
[ContentType("csharp")]
[TextViewRole(PredefinedTextViewRoles.Document)]
internal sealed class TestAdornmentProvider : IWpfTextViewCreationListener
Uno spazio negoziale è uno che occupa lo spazio allo stesso livello del testo. Per creare questo tipo di strumento decorativo, è necessario definire una classe di tag che eredita da SpaceNegotiatingAdornmentTag, che definisce la quantità di spazio occupata dall'adornamento.
Come per tutte le decorazioni, è necessario esportare la definizione del livello di adornazione.
[Export]
[Name("TestAdornment")]
[Order(After = DefaultAdornmentLayers.Text)]
internal AdornmentLayerDefinition testAdornmentLayer;
Per creare un'istanza dello strumento decorativo per la negoziazione dello spazio, è necessario creare una classe che implementa ITaggerProvider, oltre alla classe che implementa IWpfTextViewCreationListener (come con altri tipi di oggetti decorativi).
Per registrare il provider di tagger, è necessario esportarlo insieme agli attributi seguenti:
ContentTypeAttribute: tipo di contenuto (ad esempio, "text" o "code") per il quale la decorazione è valida.
TextViewRoleAttribute: tipo di visualizzazione testo per cui questo tag o strumento decorativo è valido. La classe PredefinedTextViewRoles ha il set di ruoli di visualizzazione testo predefiniti. Ad esempio, Document viene usato principalmente per le visualizzazioni di testo dei file. Interactive viene usato per le visualizzazioni di testo che un utente può modificare o spostarsi usando un mouse e una tastiera. Esempi di Interactive visualizzazioni sono la visualizzazione testo dell'editor e la finestra Output .
TagTypeAttribute: tipo di tag o adornamento definito. È necessario aggiungere un secondo TagTypeAttribute per SpaceNegotiatingAdornmentTag.
L'esempio seguente mostra gli attributi di esportazione nel provider di tagger per un tag di adornamento negoziale.
[Export(typeof(ITaggerProvider))]
[ContentType("text")]
[TextViewRole(PredefinedTextViewRoles.Document)]
[TagType(typeof(SpaceNegotiatingAdornmentTag))]
[TagType(typeof(TestSpaceNegotiatingTag))]
internal sealed class TestTaggerProvider : ITaggerProvider
Estensione dei processori del mouse
È possibile aggiungere una gestione speciale per l'input del mouse. Creare una classe che eredita da MouseProcessorBase ed eseguire l'override degli eventi del mouse per l'input da gestire. È inoltre necessario implementarlo IMouseProcessorProvider in una seconda classe ed esportarlo insieme a ContentTypeAttribute che specifica il tipo di contenuto (ad esempio, "text" o "code") per il quale il gestore del mouse è valido.
L'esempio seguente mostra gli attributi di esportazione in un provider del processore del mouse.
[Export(typeof(IMouseProcessorProvider))]
[Name("test mouse processor")]
[ContentType("text")]
[TextViewRole(PredefinedTextViewRoles.Interactive)]
internal sealed class TestMouseProcessorProvider : IMouseProcessorProvider
Estendere i gestori di rilascio
È possibile personalizzare il comportamento dei gestori di rilascio per tipi specifici di testo creando una classe che implementa IDropHandler e una seconda classe che implementa IDropHandlerProvider per creare il gestore di rilascio. È necessario esportare il gestore di rilascio insieme agli attributi seguenti:
DropFormatAttribute: formato di testo per il quale il gestore di rilascio è valido. I formati seguenti vengono gestiti in ordine di priorità dal più alto al più basso:
Qualsiasi formato personalizzato
Filedrop
EnhancedMetafile
Waveaudio
Riff
Dif
Impostazioni locali
Tavolozza
PenData
Serializable
SimbolicoLink
Xaml
XamlPackage
Tiff
Bitmap
Dib
MetafilePicture
CSV
System.String
Formato HTML
Unicodetext
OEMText
Testo
NameAttribute: nome del gestore di rilascio.
OrderAttribute: l'ordinamento del gestore di rilascio prima o dopo il gestore di rilascio predefinito. Il gestore di rilascio predefinito per Visual Studio è denominato "DefaultFileDropHandler".
Nell'esempio seguente vengono illustrati gli attributi di esportazione in un provider del gestore di rilascio.
[Export(typeof(IDropHandlerProvider))]
[DropFormat("Text")]
[Name("TestDropHandler")]
[Order(Before="DefaultFileDropHandler")]
internal class TestDropHandlerProvider : IDropHandlerProvider
Estensione delle opzioni dell'editor
È possibile definire opzioni valide solo in un determinato ambito, ad esempio in una visualizzazione testo. L'editor fornisce questo set di opzioni predefinite: opzioni dell'editor, opzioni di visualizzazione e opzioni di visualizzazione di Windows Presentation Foundation (WPF). Queste opzioni sono disponibili in DefaultOptions, DefaultTextViewOptionse DefaultWpfViewOptions.
Per aggiungere una nuova opzione, derivare una classe da una di queste classi di definizione di opzione:
-
Nell'esempio seguente viene illustrato come esportare una definizione di opzione con un valore booleano.
[Export(typeof(EditorOptionDefinition))]
internal sealed class TestOption : EditorOptionDefinition<bool>
Estendere IntelliSense
IntelliSense è un termine generale per un gruppo di funzionalità che forniscono informazioni sul testo strutturato e sul completamento delle istruzioni. Queste funzionalità includono il completamento delle istruzioni, la Guida alla firma, le informazioni rapide e le lampadine. Il completamento dell'istruzione consente agli utenti di digitare correttamente una parola chiave del linguaggio o un nome membro. La Guida alla firma visualizza la firma o le firme per il metodo appena digitato dall'utente. Le informazioni rapide visualizzano una firma completa per un tipo o un nome di membro quando il mouse si posiziona su di esso. La lampadina fornisce azioni aggiuntive per determinati identificatori in determinati contesti, ad esempio ridenominazione di tutte le occorrenze di una variabile dopo la ridenominazione di un'occorrenza.
La progettazione di una funzionalità IntelliSense è molto identica in tutti i casi:
Un broker IntelliSense è responsabile del processo complessivo.
Una sessione IntelliSense rappresenta la sequenza di eventi tra il trigger del relatore e il commit o l'annullamento della selezione. La sessione viene in genere attivata da alcuni movimenti dell'utente.
Un controller IntelliSense è responsabile della decisione dell'avvio e della fine della sessione. Decide anche quando eseguire il commit delle informazioni e quando la sessione deve essere annullata.
Un'origine IntelliSense fornisce il contenuto e decide la corrispondenza migliore.
Un relatore IntelliSense è responsabile della visualizzazione del contenuto.
Nella maggior parte dei casi, è consigliabile fornire almeno un'origine e un controller. È anche possibile fornire un relatore se si vuole personalizzare lo schermo.
Implementare un'origine IntelliSense
Per personalizzare un'origine, è necessario implementare una o più interfacce di origine seguenti:
Importante
ISmartTagSource è stato deprecato a favore di ISuggestedActionsSource.
Inoltre, è necessario implementare un provider dello stesso tipo:
Importante
ISmartTagSourceProvider è stato deprecato a favore di ISuggestedActionsSourceProvider.
È necessario esportare il provider insieme agli attributi seguenti:
NameAttribute: nome dell'origine.
ContentTypeAttribute: tipo di contenuto (ad esempio, "text" o "code") a cui si applica l'origine.
OrderAttribute: l'ordine in cui deve essere visualizzata l'origine (rispetto ad altre origini).
Nell'esempio seguente vengono illustrati gli attributi di esportazione in un provider di origine di completamento.
Export(typeof(ICompletionSourceProvider))]
[Name(" Test Statement Completion Provider")]
[Order(Before = "default")]
[ContentType("text")]
internal class TestCompletionSourceProvider : ICompletionSourceProvider
Per altre informazioni sull'implementazione di origini IntelliSense, vedere le procedure dettagliate seguenti:
Procedura dettagliata: Visualizzare le descrizioni comando QuickInfo
Procedura dettagliata: Visualizzare il completamento istruzioni
Implementare un controller IntelliSense
Per personalizzare un controller, è necessario implementare l'interfaccia IIntellisenseController . Inoltre, è necessario implementare un provider di controller insieme agli attributi seguenti:
NameAttribute: nome del controller.
ContentTypeAttribute: tipo di contenuto (ad esempio, "text" o "code") a cui si applica il controller.
OrderAttribute: l'ordine in cui deve essere visualizzato il controller (rispetto ad altri controller).
Nell'esempio seguente vengono illustrati gli attributi di esportazione in un provider di controller di completamento.
Export(typeof(IIntellisenseControllerProvider))]
[Name(" Test Controller Provider")]
[Order(Before = "default")]
[ContentType("text")]
internal class TestIntellisenseControllerProvider : IIntellisenseControllerProvider
Per altre informazioni sull'uso dei controller IntelliSense, vedere le procedure dettagliate seguenti: