Не уверен, что если вы попробовали приведенную ниже ссылку, она должна соответствовать вашему требованию о тегах "text-относительный"
https://docs.microsoft.com/en-us/visualstudio/extensibility/creating-an-extension-with-an-editor-item-template?view=vs-2017
Создать расширение для текстового обозначения
Шаблон редактирования текста в редакторе создает относительное к тексту украшение, которое украшает все экземпляры текстового символа «а» с помощью прямоугольника с красным контуром и синим фоном. Он относится к тексту, поскольку в поле всегда накладываются символы 'a' , даже если они перемещены или переформатированы.
Добавить примеры кодов:
public TextAdornment1(IWpfTextView view)
{
if (view == null)
{
throw new ArgumentNullException("view");
}
this.layer = view.GetAdornmentLayer("TextAdornment1");
this.view = view;
this.view.LayoutChanged += this.OnLayoutChanged;
// Create the pen and brush to color the box behind the a's
this.brush = new SolidColorBrush(Color.FromArgb(0x20, 0x00, 0x00, 0xff));
this.brush.Freeze();
var penBrush = new SolidColorBrush(Colors.Red);
penBrush.Freeze();
this.pen = new Pen(penBrush, 0.5);
this.pen.Freeze();
}
internal void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
{
foreach (ITextViewLine line in e.NewOrReformattedLines)
{
this.CreateVisuals(line);
}
}
private void CreateVisuals(ITextViewLine line)
{
IWpfTextViewLineCollection textViewLines = this.view.TextViewLines;
// Loop through each character, and place a box around any 'a'
for (int charIndex = line.Start; charIndex < line.End; charIndex++)
{
if (this.view.TextSnapshot[charIndex] == 'a')
{
SnapshotSpan span = new SnapshotSpan(this.view.TextSnapshot, Span.FromBounds(charIndex, charIndex + 1));
Geometry geometry = textViewLines.GetMarkerGeometry(span);
if (geometry != null)
{
var drawing = new GeometryDrawing(this.brush, this.pen, geometry);
drawing.Freeze();
var drawingImage = new DrawingImage(drawing);
drawingImage.Freeze();
var image = new Image
{
Source = drawingImage,
};
// Align the image with the top of the bounds of the text geometry
Canvas.SetLeft(image, geometry.Bounds.Left);
Canvas.SetTop(image, geometry.Bounds.Top);
this.layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null);
}
}
}
}