Поделиться через


Пошаговое руководство. Создание глифа поля

Внешний вид полей редактора можно настроить с помощью настраиваемых расширений редактора. В этом пошаговом руководстве поместите пользовательский глиф на поле индикатора всякий раз, когда слово "todo" отображается в комментарии кода.

Создание проекта MEF

  1. Создайте проект VSIX на C#. (В Диалоговое окно "Новый проект" , выберите Visual C# / Расширяемость, а затем ПРОЕКТ VSIX.) Назовите решение TodoGlyphTest.

  2. Добавьте элемент проекта классификатора редактора. Дополнительные сведения: Создание расширения с помощью шаблона элемента редактора.

  3. Удалите файлы существующих классов.

Определение глифа

Определите глиф, запустив IGlyphFactory интерфейс.

Определение глифа

  1. Добавьте файл класса с именем TodoGlyphFactory.

  2. Добавьте следующий код с помощью объявлений.

    using System.ComponentModel.Composition;
    using System.Windows;
    using System.Windows.Shapes;
    using System.Windows.Media;
    using System.Windows.Controls;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.Text.Formatting;
    using Microsoft.VisualStudio.Text.Tagging;
    using Microsoft.VisualStudio.Utilities;
    
  3. Добавьте класс с именем TodoGlyphFactory , который реализует IGlyphFactory.

    internal class TodoGlyphFactory : IGlyphFactory
    
  4. Добавьте частное поле, определяющее размеры глифа.

    const double m_glyphSize = 16.0;
    
  5. Реализуйте, GenerateGlyph определив элемент пользовательского интерфейса глифа. TodoTag определяется далее в этом пошаговом руководстве.

    public UIElement GenerateGlyph(IWpfTextViewLine line, IGlyphTag tag)
    {
        // Ensure we can draw a glyph for this marker.
        if (tag == null || !(tag is TodoTag))
        {
            return null;
        }
    
        System.Windows.Shapes.Ellipse ellipse = new Ellipse();
        ellipse.Fill = Brushes.LightBlue;
        ellipse.StrokeThickness = 2;
        ellipse.Stroke = Brushes.DarkBlue;
        ellipse.Height = m_glyphSize;
        ellipse.Width = m_glyphSize;
    
        return ellipse;
    }
    
  6. Добавьте класс с именем TodoGlyphFactoryProvider , который реализует IGlyphFactoryProvider. Экспортируйте этот класс с NameAttribute помощью todoGlyph, объекта After VsTextMarker, OrderAttributeContentTypeAttribute кода и TagTypeAttribute todoTag.

    [Export(typeof(IGlyphFactoryProvider))]
    [Name("TodoGlyph")]
    [Order(After = "VsTextMarker")]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    internal sealed class TodoGlyphFactoryProvider : IGlyphFactoryProvider
    
  7. GetGlyphFactory Реализуйте метод путем создания экземпляра TodoGlyphFactory.

    public IGlyphFactory GetGlyphFactory(IWpfTextView view, IWpfTextViewMargin margin)
    {
        return new TodoGlyphFactory();
    }
    

Определение тега и тега Todo

Определите связь между элементом пользовательского интерфейса, определенным на предыдущих шагах, и полем индикатора. Создайте тип тега и тег и экспортируйте его с помощью поставщика тегов.

Определение тега и тега todo

  1. Добавьте новый файл класса в проект и назовите его TodoTagger.

  2. Добавьте приведенные ниже импортированные данные.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using Microsoft.VisualStudio.Text;
    using Microsoft.VisualStudio.Text.Tagging;
    using Microsoft.VisualStudio.Text.Editor;
    using Microsoft.VisualStudio.Text.Classification;
    using Microsoft.VisualStudio.Utilities;
    
  3. Добавьте класс с именем TodoTag.

    internal class TodoTag : IGlyphTag
    
  4. Измените класс с именем TodoTagger , реализующий ITagger<T> тип TodoTag.

    internal class TodoTagger : ITagger<TodoTag>
    
  5. В класс добавьте частные TodoTagger поля для текста, IClassifier который будет находиться в диапазонах классификации.

    private IClassifier m_classifier;
    private const string m_searchText = "todo";
    
  6. Добавьте конструктор, который задает классификатор.

    internal TodoTagger(IClassifier classifier)
    {
        m_classifier = classifier;
    }
    
  7. GetTags Реализуйте метод, найдя все диапазоны классификации, имена которых включают слово "комментарий" и текст которого содержит текст поиска. При обнаружении текста поиска возвращает новый TagSpan<T> тип TodoTag.

    IEnumerable<ITagSpan<TodoTag>> ITagger<TodoTag>.GetTags(NormalizedSnapshotSpanCollection spans)
    {
        foreach (SnapshotSpan span in spans)
        {
            //look at each classification span \
            foreach (ClassificationSpan classification in m_classifier.GetClassificationSpans(span))
            {
                //if the classification is a comment
                if (classification.ClassificationType.Classification.ToLower().Contains("comment"))
                {
                    //if the word "todo" is in the comment,
                    //create a new TodoTag TagSpan
                    int index = classification.Span.GetText().ToLower().IndexOf(m_searchText);
                    if (index != -1)
                    {
                        yield return new TagSpan<TodoTag>(new SnapshotSpan(classification.Span.Start + index, m_searchText.Length), new TodoTag());
                    }
                }
            }
        }
    }
    
  8. Объявите TagsChanged событие.

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
    
  9. Добавьте класс с именем TodoTaggerProvider , реализующий ITaggerProviderи экспортируйте его с ContentTypeAttribute помощью кода и TagTypeAttribute объекта TodoTag.

    [Export(typeof(ITaggerProvider))]
    [ContentType("code")]
    [TagType(typeof(TodoTag))]
    class TodoTaggerProvider : ITaggerProvider
    
  10. Импортируйте IClassifierAggregatorService.

    [Import]
    internal IClassifierAggregatorService AggregatorService;
    
  11. CreateTagger Реализуйте метод путем создания экземпляра TodoTagger.

    public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
    {
        if (buffer == null)
        {
            throw new ArgumentNullException("buffer");
        }
    
        return new TodoTagger(AggregatorService.GetClassifier(buffer)) as ITagger<T>;
    }
    

Сборка и проверка кода

Чтобы протестировать этот код, создайте решение TodoGlyphTest и запустите его в экспериментальном экземпляре.

Создание и тестирование решения TodoGlyphTest

  1. Постройте решение.

  2. Запустите проект, нажав клавишу F5. Запускается второй экземпляр Visual Studio.

  3. Убедитесь, что отображается поле индикатора. (В Меню "Сервис" выберите пункт "Параметры". На странице текстового редактора убедитесь, что выбрано поле индикатора.)

  4. Откройте файл кода с комментариями. Добавьте слово "todo" в один из разделов комментариев.

  5. Светло-синий круг с темно-синей контуром отображается в поле индикатора слева от окна кода.