Procédure pas à pas : mode PlanWalkthrough: Outlining

Configurer les fonctionnalités reposant sur le langage comme le mode plan en définissant les types de zones de texte que vous souhaitez développer ou réduire.Set up language-based features such as outlining by defining the kinds of text regions you want to expand or collapse. Vous pouvez définir des régions dans le contexte d’un service de langage, ou définir votre propre type de contenu et d’extension de nom fichier et s’appliquent de la définition de la région à uniquement à ce type ou appliquer les définitions de la région à un type de contenu existant (par exemple, « text »).You can define regions in the context of a language service, or define your own file name extension and content type and apply the region definition to only that type, or apply the region definitions to an existing content type (such as "text"). Cette procédure pas à pas montre comment définir et afficher les régions en mode plan.This walkthrough shows how to define and display outlining regions.

PrérequisPrerequisites

À partir de Visual Studio 2015, vous n’installez pas le Kit de développement logiciel Visual Studio à partir du centre de téléchargement.Starting in Visual Studio 2015, you don't install the Visual Studio SDK from the download center. Il est inclus comme fonctionnalité facultative dans le programme d’installation de Visual Studio.It's included as an optional feature in Visual Studio setup. Vous pouvez également installer le kit SDK VS par la suite.You can also install the VS SDK later on. Pour plus d’informations, consultez installer le SDK Visual Studio.For more information, see Install the Visual Studio SDK.

Créer un projet Managed Extensibility Framework (MEF)Create a Managed Extensibility Framework (MEF) project

Pour créer un projet MEFTo create a MEF project

  1. Créez un projet VSIX.Create a VSIX project. Nommez la solution OutlineRegionTest.Name the solution OutlineRegionTest.

  2. Ajouter un modèle d’élément de classifieur d’éditeur au projet.Add an Editor Classifier item template to the project. Pour plus d’informations, consultez créer une extension avec un éditeur de modèle d’élément.For more information, see Create an extension with an editor item template.

  3. Supprimez les fichiers de classe existants.Delete the existing class files.

Implémenter une balise en mode planImplement an outlining tagger

Régions en mode plan sont marquées par un type de balise (OutliningRegionTag).Outlining regions are marked by a kind of tag (OutliningRegionTag). Cette balise fournit la norme de comportement de mise en relief.This tag provides the standard outlining behavior. La zone peut être développée ou réduite.The outlined region can be expanded or collapsed. La région avec contour est marquée par un signe Plus (+) s’il est réduit ou un signe moins (-) si elle est développée, et la région développée est délimitée par une ligne verticale.The outlined region is marked by a Plus sign (+) if it's collapsed or a Minus sign (-) if it's expanded, and the expanded region is demarcated by a vertical line.

Les étapes suivantes montrent comment définir une balise qui crée des régions en mode plan pour toutes les régions délimitées par des crochets ([,]).The following steps show how to define a tagger that creates outlining regions for all the regions delimited by the brackets ([,]).

Pour implémenter une balise en mode planTo implement an outlining tagger

  1. Ajoutez un fichier de classe et nommez-le OutliningTagger.Add a class file and name it OutliningTagger.

  2. Importez les espaces de noms suivants.Import the following namespaces.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio.Text.Outlining;
    using Microsoft.VisualStudio.Text.Tagging;
    using Microsoft.VisualStudio.Utilities;
    using Microsoft.VisualStudio.Text;
    
    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Text
    Imports System.ComponentModel.Composition
    Imports Microsoft.VisualStudio.Text.Outlining
    Imports Microsoft.VisualStudio.Text.Tagging
    Imports Microsoft.VisualStudio.Utilities
    Imports Microsoft.VisualStudio.Text
    
  3. Créez une classe nommée OutliningTagger, et qu’elle implémente ITagger<T>:Create a class named OutliningTagger, and have it implement ITagger<T>:

    internal sealed class OutliningTagger : ITagger<IOutliningRegionTag>
    
    Friend NotInheritable Class OutliningTagger
        Implements ITagger(Of IOutliningRegionTag)
    
  4. Ajouter des champs pour effectuer le suivi de la mémoire tampon de texte et l’instantané et accumuler les ensembles de lignes qui doivent être marqués comme régions en mode plan.Add some fields to track the text buffer and snapshot and to accumulate the sets of lines that should be tagged as outlining regions. Ce code inclut une liste d’objets de région (à définir ultérieurement) qui représentent les régions en mode plan.This code includes a list of Region objects (to be defined later) that represent the outlining regions.

    string startHide = "[";     //the characters that start the outlining region
    string endHide = "]";       //the characters that end the outlining region
    string ellipsis = "...";    //the characters that are displayed when the region is collapsed
    string hoverText = "hover text"; //the contents of the tooltip for the collapsed span
    ITextBuffer buffer;
    ITextSnapshot snapshot;
    List<Region> regions;
    
    'the characters that start the outlining region
    Private startHide As String = "["
    'the characters that end the outlining region
    Private endHide As String = "]"
    'the characters that are displayed when the region is collapsed
    Private ellipsis As String = "..."
    'the contents of the tooltip for the collapsed span
    Private hoverText As String = "hover text"
    Private buffer As ITextBuffer
    Private snapshot As ITextSnapshot
    Private regions As List(Of Region)
    
  5. Ajoutez un constructeur de la balise qui initialise les champs, analyse de la mémoire tampon, et ajoute un gestionnaire d’événements pour le Changed événement.Add a tagger constructor that initializes the fields, parses the buffer, and adds an event handler to the Changed event.

    public OutliningTagger(ITextBuffer buffer)
    {
        this.buffer = buffer;
        this.snapshot = buffer.CurrentSnapshot;
        this.regions = new List<Region>();
        this.ReParse();
        this.buffer.Changed += BufferChanged;
    }
    
    Public Sub New(ByVal buffer As ITextBuffer)
        Me.buffer = buffer
        Me.snapshot = buffer.CurrentSnapshot
        Me.regions = New List(Of Region)()
        Me.ReParse()
        AddHandler Me.buffer.Changed, AddressOf BufferChanged
    End Sub
    
  6. Implémentez le GetTags s’étend de méthode qui instancie la balise.Implement the GetTags method, which instantiates the tag spans. Cet exemple suppose que les étendues dans le NormalizedSpanCollection passé à la méthode sont contiguës, bien qu’il ne peut pas être toujours le cas.This example assumes that the spans in the NormalizedSpanCollection passed in to the method are contiguous, although it may not always be the case. Cette méthode instancie un nouvel intervalle de balise pour chacune des régions en mode plan.This method instantiates a new tag span for each of the outlining regions.

    public IEnumerable<ITagSpan<IOutliningRegionTag>> GetTags(NormalizedSnapshotSpanCollection spans)
    {
        if (spans.Count == 0)
            yield break;
        List<Region> currentRegions = this.regions;
        ITextSnapshot currentSnapshot = this.snapshot;
        SnapshotSpan entire = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End).TranslateTo(currentSnapshot, SpanTrackingMode.EdgeExclusive);
        int startLineNumber = entire.Start.GetContainingLine().LineNumber;
        int endLineNumber = entire.End.GetContainingLine().LineNumber;
        foreach (var region in currentRegions)
        {
            if (region.StartLine <= endLineNumber &&
                region.EndLine >= startLineNumber)
            {
                var startLine = currentSnapshot.GetLineFromLineNumber(region.StartLine);
                var endLine = currentSnapshot.GetLineFromLineNumber(region.EndLine);
    
                //the region starts at the beginning of the "[", and goes until the *end* of the line that contains the "]".
                yield return new TagSpan<IOutliningRegionTag>(
                    new SnapshotSpan(startLine.Start + region.StartOffset,
                    endLine.End),
                    new OutliningRegionTag(false, false, ellipsis, hoverText));
            }
        }
    }
    
    Public Function GetTags(ByVal spans As NormalizedSnapshotSpanCollection) As IEnumerable(Of ITagSpan(Of IOutliningRegionTag)) Implements ITagger(Of Microsoft.VisualStudio.Text.Tagging.IOutliningRegionTag).GetTags
        If spans.Count = 0 Then
            Return Nothing
            Exit Function
        End If
        Dim currentRegions As List(Of Region) = Me.regions
        Dim currentSnapshot As ITextSnapshot = Me.snapshot
        Dim entire As SnapshotSpan = New SnapshotSpan(spans(0).Start, spans(spans.Count - 1).[End]).TranslateTo(currentSnapshot, SpanTrackingMode.EdgeExclusive)
        Dim startLineNumber As Integer = entire.Start.GetContainingLine().LineNumber
        Dim endLineNumber As Integer = entire.[End].GetContainingLine().LineNumber
    
        Dim list As List(Of ITagSpan(Of IOutliningRegionTag))
        list = New List(Of ITagSpan(Of IOutliningRegionTag))()
    
        For Each region In currentRegions
            If region.StartLine <= endLineNumber AndAlso region.EndLine >= startLineNumber Then
                Dim startLine = currentSnapshot.GetLineFromLineNumber(region.StartLine)
                Dim endLine = currentSnapshot.GetLineFromLineNumber(region.EndLine)
    
                'the region starts at the beginning of the "[", and goes until the *end* of the line that contains the "]".
                list.Add(New TagSpan(Of IOutliningRegionTag)(New SnapshotSpan(startLine.Start + region.StartOffset, endLine.End),
                New OutliningRegionTag(False, False, ellipsis, hoverText)))
            End If
        Next
        Return list
    End Function
    
  7. Déclarez un TagsChanged Gestionnaire d’événements.Declare a TagsChanged event handler.

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
    Public Event TagsChanged As EventHandler(Of SnapshotSpanEventArgs) Implements ITagger(Of IOutliningRegionTag).TagsChanged
    
  8. Ajouter un BufferChanged Gestionnaire d’événements qui répond à Changed événements en analysant la mémoire tampon de texte.Add a BufferChanged event handler that responds to Changed events by parsing the text buffer.

    void BufferChanged(object sender, TextContentChangedEventArgs e)
    {
        // If this isn't the most up-to-date version of the buffer, then ignore it for now (we'll eventually get another change event).
        if (e.After != buffer.CurrentSnapshot)
            return;
        this.ReParse();
    }
    
    Private Sub BufferChanged(ByVal sender As Object, ByVal e As TextContentChangedEventArgs)
        ' If this isn't the most up-to-date version of the buffer, then ignore it for now (we'll eventually get another change event).
        If e.After IsNot buffer.CurrentSnapshot Then
            Exit Sub
        End If
        Me.ReParse()
    End Sub
    
  9. Ajoutez une méthode qui analyse la mémoire tampon.Add a method that parses the buffer. L’exemple fourni ici est à titre d’illustration uniquement.The example given here is for illustration only. Mode synchrone, il analyse la mémoire tampon dans les régions en mode plan imbriquées.It synchronously parses the buffer into nested outlining regions.

    void ReParse()
    {
        ITextSnapshot newSnapshot = buffer.CurrentSnapshot;
        List<Region> newRegions = new List<Region>();
    
        //keep the current (deepest) partial region, which will have
        // references to any parent partial regions.
        PartialRegion currentRegion = null;
    
        foreach (var line in newSnapshot.Lines)
        {
            int regionStart = -1;
            string text = line.GetText();
    
            //lines that contain a "[" denote the start of a new region.
            if ((regionStart = text.IndexOf(startHide, StringComparison.Ordinal)) != -1)
            {
                int currentLevel = (currentRegion != null) ? currentRegion.Level : 1;
                int newLevel;
                if (!TryGetLevel(text, regionStart, out newLevel))
                    newLevel = currentLevel + 1;
    
                //levels are the same and we have an existing region;
                //end the current region and start the next
                if (currentLevel == newLevel && currentRegion != null)
                {
                    newRegions.Add(new Region()
                    {
                        Level = currentRegion.Level,
                        StartLine = currentRegion.StartLine,
                        StartOffset = currentRegion.StartOffset,
                        EndLine = line.LineNumber
                    });
    
                    currentRegion = new PartialRegion()
                    {
                        Level = newLevel,
                        StartLine = line.LineNumber,
                        StartOffset = regionStart,
                        PartialParent = currentRegion.PartialParent
                    };
                }
                //this is a new (sub)region
                else
                {
                    currentRegion = new PartialRegion()
                    {
                        Level = newLevel,
                        StartLine = line.LineNumber,
                        StartOffset = regionStart,
                        PartialParent = currentRegion
                    };
                }
            }
            //lines that contain "]" denote the end of a region
            else if ((regionStart = text.IndexOf(endHide, StringComparison.Ordinal)) != -1)
            {
                int currentLevel = (currentRegion != null) ? currentRegion.Level : 1;
                int closingLevel;
                if (!TryGetLevel(text, regionStart, out closingLevel))
                    closingLevel = currentLevel;
    
                //the regions match
                if (currentRegion != null &&
                    currentLevel == closingLevel)
                {
                    newRegions.Add(new Region()
                    {
                        Level = currentLevel,
                        StartLine = currentRegion.StartLine,
                        StartOffset = currentRegion.StartOffset,
                        EndLine = line.LineNumber
                    });
    
                    currentRegion = currentRegion.PartialParent;
                }
            }
        }
    
        //determine the changed span, and send a changed event with the new spans
        List<Span> oldSpans =
            new List<Span>(this.regions.Select(r => AsSnapshotSpan(r, this.snapshot)
                .TranslateTo(newSnapshot, SpanTrackingMode.EdgeExclusive)
                .Span));
        List<Span> newSpans =
                new List<Span>(newRegions.Select(r => AsSnapshotSpan(r, newSnapshot).Span));
    
        NormalizedSpanCollection oldSpanCollection = new NormalizedSpanCollection(oldSpans);
        NormalizedSpanCollection newSpanCollection = new NormalizedSpanCollection(newSpans);
    
        //the changed regions are regions that appear in one set or the other, but not both.
        NormalizedSpanCollection removed =
        NormalizedSpanCollection.Difference(oldSpanCollection, newSpanCollection);
    
        int changeStart = int.MaxValue;
        int changeEnd = -1;
    
        if (removed.Count > 0)
        {
            changeStart = removed[0].Start;
            changeEnd = removed[removed.Count - 1].End;
        }
    
        if (newSpans.Count > 0)
        {
            changeStart = Math.Min(changeStart, newSpans[0].Start);
            changeEnd = Math.Max(changeEnd, newSpans[newSpans.Count - 1].End);
        }
    
        this.snapshot = newSnapshot;
        this.regions = newRegions;
    
        if (changeStart <= changeEnd)
        {
            ITextSnapshot snap = this.snapshot;
            if (this.TagsChanged != null)
                this.TagsChanged(this, new SnapshotSpanEventArgs(
                    new SnapshotSpan(this.snapshot, Span.FromBounds(changeStart, changeEnd))));
        }
    }
    
    Private Sub ReParse()
        Dim newSnapshot As ITextSnapshot = buffer.CurrentSnapshot
        Dim newRegions As New List(Of Region)()
    
        'keep the current (deepest) partial region, which will have
        ' references to any parent partial regions.
        Dim currentRegion As PartialRegion = Nothing
    
        For Each line In newSnapshot.Lines
            Dim regionStart As Integer = -1
            Dim text As String = line.GetText()
    
            'lines that contain a "[" denote the start of a new region.
            If text.IndexOf(startHide, StringComparison.Ordinal) <> -1 Then
                regionStart = text.IndexOf(startHide, StringComparison.Ordinal)
                Dim currentLevel As Integer = If((currentRegion IsNot Nothing), currentRegion.Level, 1)
                Dim newLevel As Integer
                If Not TryGetLevel(text, regionStart, newLevel) Then
                    newLevel = currentLevel + 1
                End If
    
                'levels are the same and we have an existing region;
                'end the current region and start the next
                If currentLevel = newLevel AndAlso currentRegion IsNot Nothing Then
                    Dim newRegion = New Region()
                    newRegion.Level = currentRegion.Level
                    newRegion.StartLine = currentRegion.StartLine
                    newRegion.StartOffset = currentRegion.StartOffset
                    newRegion.EndLine = line.LineNumber
                    newRegions.Add(newRegion)
    
                    currentRegion = New PartialRegion()
                    currentRegion.Level = newLevel
                    currentRegion.StartLine = line.LineNumber
                    currentRegion.StartOffset = regionStart
                    currentRegion.PartialParent = currentRegion.PartialParent
    
                Else
                    'this is a new (sub)region
                    currentRegion = New PartialRegion()
                    currentRegion.Level = newLevel
                    currentRegion.StartLine = line.LineNumber
                    currentRegion.StartOffset = regionStart
                    currentRegion.PartialParent = currentRegion
                End If
                'lines that contain "]" denote the end of a region
            ElseIf (text.IndexOf(endHide, StringComparison.Ordinal)) <> -1 Then
                regionStart = text.IndexOf(endHide, StringComparison.Ordinal)
                Dim currentLevel As Integer = If((currentRegion IsNot Nothing), currentRegion.Level, 1)
                Dim closingLevel As Integer
                If Not TryGetLevel(text, regionStart, closingLevel) Then
                    closingLevel = currentLevel
                End If
    
                'the regions match
                If currentRegion IsNot Nothing AndAlso currentLevel = closingLevel Then
                    Dim newRegion As Region
                    newRegion = New Region()
                    newRegion.Level = currentLevel
                    newRegion.StartLine = currentRegion.StartLine
                    newRegion.StartOffset = currentRegion.StartOffset
                    newRegion.EndLine = line.LineNumber
                    newRegions.Add(newRegion)
    
                    currentRegion = currentRegion.PartialParent
                End If
            End If
        Next
        'determine the changed span, and send a changed event with the new spans
        Dim oldSpans As New List(Of Span)(Me.regions.[Select](Function(r) AsSnapshotSpan(r, Me.snapshot).TranslateTo(newSnapshot, SpanTrackingMode.EdgeExclusive).Span))
        Dim newSpans As New List(Of Span)(newRegions.[Select](Function(r) AsSnapshotSpan(r, newSnapshot).Span))
    
        Dim oldSpanCollection As New NormalizedSpanCollection(oldSpans)
        Dim newSpanCollection As New NormalizedSpanCollection(newSpans)
    
        'the changed regions are regions that appear in one set or the other, but not both.
        Dim removed As NormalizedSpanCollection = NormalizedSpanCollection.Difference(oldSpanCollection, newSpanCollection)
    
        Dim changeStart As Integer = Integer.MaxValue
        Dim changeEnd As Integer = -1
    
        If removed.Count > 0 Then
            changeStart = removed(0).Start
            changeEnd = removed(removed.Count - 1).[End]
        End If
    
        If newSpans.Count > 0 Then
            changeStart = Math.Min(changeStart, newSpans(0).Start)
            changeEnd = Math.Max(changeEnd, newSpans(newSpans.Count - 1).[End])
        End If
    
        Me.snapshot = newSnapshot
        Me.regions = newRegions
    
        If changeStart <= changeEnd Then
            Dim snap As ITextSnapshot = Me.snapshot
            RaiseEvent TagsChanged(Me, New SnapshotSpanEventArgs(New SnapshotSpan(Me.snapshot, Span.FromBounds(changeStart, changeEnd))))
        End If
    End Sub
    
  10. La méthode d’assistance suivante obtient un entier qui représente le niveau de la fonctionnalité mode plan, telles que 1 est la paire d’accolades à l’extrême gauche.The following helper method gets an integer that represents the level of the outlining, such that 1 is the leftmost brace pair.

    static bool TryGetLevel(string text, int startIndex, out int level)
    {
        level = -1;
        if (text.Length > startIndex + 3)
        {
            if (int.TryParse(text.Substring(startIndex + 1), out level))
                return true;
        }
    
        return false;
    }
    
    Private Shared Function TryGetLevel(ByVal text As String, ByVal startIndex As Integer, ByRef level As Integer) As Boolean
        level = -1
        If text.Length > startIndex + 3 Then
            If Integer.TryParse(text.Substring(startIndex + 1), level) Then
                Return True
            End If
        End If
    
        Return False
    End Function
    
  11. La méthode d’assistance suivante traduit un SnapshotSpan une région (définie plus loin dans cet article).The following helper method translates a Region (defined later in this article) into a SnapshotSpan.

    static SnapshotSpan AsSnapshotSpan(Region region, ITextSnapshot snapshot)
    {
        var startLine = snapshot.GetLineFromLineNumber(region.StartLine);
        var endLine = (region.StartLine == region.EndLine) ? startLine
             : snapshot.GetLineFromLineNumber(region.EndLine);
        return new SnapshotSpan(startLine.Start + region.StartOffset, endLine.End);
    }
    
    Private Shared Function AsSnapshotSpan(ByVal region As Region, ByVal snapshot As ITextSnapshot) As SnapshotSpan
        Dim startLine = snapshot.GetLineFromLineNumber(region.StartLine)
        Dim endLine = If((region.StartLine = region.EndLine), startLine, snapshot.GetLineFromLineNumber(region.EndLine))
        Return New SnapshotSpan(startLine.Start + region.StartOffset, endLine.[End])
    End Function
    
  12. Le code suivant est à titre d’illustration uniquement.The following code is for illustration only. Il définit une classe PartialRegion qui contient le numéro de ligne et l’offset du début d’une région en mode plan et une référence à la zone parent (le cas échéant).It defines a PartialRegion class that contains the line number and offset of the start of an outlining region, and a reference to the parent region (if any). Ce code permet à l’analyseur configurer imbriqués régions en mode plan.This code enables the parser to set up nested outlining regions. Une classe dérivée de la région contient une référence au numéro de ligne de la fin d’une région en mode plan.A derived Region class contains a reference to the line number of the end of an outlining region.

    class PartialRegion
    {
        public int StartLine { get; set; }
        public int StartOffset { get; set; }
        public int Level { get; set; }
        public PartialRegion PartialParent { get; set; }
    }
    
    class Region : PartialRegion
    {
        public int EndLine { get; set; }
    } 
    
    Private Class PartialRegion
        Private _StartLine As Integer
        Public Property StartLine() As Integer
            Get
                Return _StartLine
            End Get
            Set(ByVal value As Integer)
                _StartLine = value
            End Set
        End Property
        Private _StartOffset As Integer
        Public Property StartOffset() As Integer
            Get
                Return _StartOffset
            End Get
            Set(ByVal value As Integer)
                _StartOffset = value
            End Set
        End Property
        Private _Level As Integer
        Public Property Level() As Integer
            Get
                Return _Level
            End Get
            Set(ByVal value As Integer)
                _Level = value
            End Set
        End Property
        Private _PartialParent As PartialRegion
        Public Property PartialParent() As PartialRegion
            Get
                Return _PartialParent
            End Get
            Set(ByVal value As PartialRegion)
                _PartialParent = value
            End Set
        End Property
    End Class
    
    Private Class Region
        Inherits PartialRegion
        Private _EndLine As Integer
        Public Property EndLine() As Integer
            Get
                Return _EndLine
            End Get
            Set(ByVal value As Integer)
                _EndLine = value
            End Set
        End Property
    End Class
    

Implémenter un fournisseur de baliseurImplement a tagger provider

Exporter un fournisseur de baliseur pour votre balise.Export a tagger provider for your tagger. Le fournisseur de baliseur crée un OutliningTagger pour une mémoire tampon du type de contenu « texte », ou autre un OutliningTagger si la mémoire tampon en comporte déjà un.The tagger provider creates an OutliningTagger for a buffer of the "text" content type, or else returns an OutliningTagger if the buffer already has one.

Pour implémenter un fournisseur de baliseurTo implement a tagger provider

  1. Créez une classe nommée OutliningTaggerProvider qui implémente ITaggerProvideret exportez-le avec les attributs ContentType et TagType.Create a class named OutliningTaggerProvider that implements ITaggerProvider, and export it with the ContentType and TagType attributes.

    [Export(typeof(ITaggerProvider))]
    [TagType(typeof(IOutliningRegionTag))]
    [ContentType("text")]
    internal sealed class OutliningTaggerProvider : ITaggerProvider
    
    <Export(GetType(ITaggerProvider))> _
    <TagType(GetType(IOutliningRegionTag))> _
    <ContentType("text")> _
    Friend NotInheritable Class OutliningTaggerProvider
        Implements ITaggerProvider
    
  2. Implémentez le CreateTagger méthode en ajoutant un OutliningTagger aux propriétés de la mémoire tampon.Implement the CreateTagger method by adding an OutliningTagger to the properties of the buffer.

    public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
    {
        //create a single tagger for each buffer.
        Func<ITagger<T>> sc = delegate() { return new OutliningTagger(buffer) as ITagger<T>; };
        return buffer.Properties.GetOrCreateSingletonProperty<ITagger<T>>(sc);
    } 
    
    Public Function CreateTagger(Of T As ITag)(ByVal buffer As ITextBuffer) As ITagger(Of T) Implements ITaggerProvider.CreateTagger
        'create a single tagger for each buffer.
        Dim sc As Func(Of ITagger(Of T)) = Function() TryCast(New OutliningTagger(buffer), ITagger(Of T))
        Return buffer.Properties.GetOrCreateSingletonProperty(Of ITagger(Of T))(sc)
    End Function
    

Générer et tester le codeBuild and test the code

Pour tester ce code, générez la solution OutlineRegionTest et exécutez-le dans l’instance expérimentale.To test this code, build the OutlineRegionTest solution and run it in the experimental instance.

Pour générer et tester la solution OutlineRegionTestTo build and test the OutlineRegionTest solution

  1. Générez la solution.Build the solution.

  2. Lorsque vous exécutez ce projet dans le débogueur, une deuxième instance de Visual Studio est démarrée.When you run this project in the debugger, a second instance of Visual Studio is started.

  3. Créer un fichier texte.Create a text file. Tapez du texte qui inclut les crochets ouvrant et le crochet fermant.Type some text that includes both the opening brackets and the closing brackets.

    [  
       Hello  
    ]  
    
  4. Il doit y avoir une région en mode plan qui inclut les deux crochets.There should be an outlining region that includes both brackets. Vous pourrez cliquer sur le signe moins à gauche de la parenthèse ouverte pour réduire la région en mode plan.You should be able to click the Minus Sign to the left of the open bracket to collapse the outlining region. Lorsque la région est réduite, le symbole de points de suspension (... ) doit apparaître à gauche de la région réduite et une fenêtre contextuelle contenant le texte texte de pointage doit apparaître lorsque vous déplacez le pointeur sur le bouton de sélection.When the region is collapsed, the ellipsis symbol (...) should appear to the left of the collapsed region, and a popup containing the text hover text should appear when you move the pointer over the ellipsis.

Voir aussiSee also

Procédure pas à pas : Lier un type de contenu à une extension de nom de fichierWalkthrough: Link a content type to a file name extension