atlaste atlaste - 19 days ago 5
C# Question

Visual Studio adornment in front of text interferes with selection

Last week, I decided to create a Visual Studio Extension for measuring C++ code coverage. Basically I needed it myself for my daily work. What I came up with was the project that can be found https://github.com/atlaste/CPPCoverage .

Most it works fine. However, I have some issues with adornment layers:

One of the features of the project is to create highlighting of the (un)covered code. Highlighting itself works fine, but it seems to interfere with the selection code of Visual Studio:

Demonstration of issue

The relevant code that's responsible for the highlighting:

private void HighlightCoverage(CoverageState[] coverdata, ITextViewLine line)
{
IWpfTextViewLineCollection textViewLines = view.TextViewLines;

int lineno = 1 + view.TextSnapshot.GetLineNumberFromPosition(line.Extent.Start);

CoverageState covered = lineno < coverdata.Length ?
coverdata[lineno] : CoverageState.Irrelevant;

if (covered != CoverageState.Irrelevant)
{
SnapshotSpan span = new SnapshotSpan(view.TextSnapshot,
Span.FromBounds(line.Start, line.End));
Geometry g = textViewLines.GetMarkerGeometry(span);
if (g != null)
{
GeometryDrawing drawing = (covered == CoverageState.Covered) ?
new GeometryDrawing(coveredBrush, coveredPen, g) :
new GeometryDrawing(uncoveredBrush, uncoveredPen, g);

drawing.Freeze();

DrawingImage drawingImage = new DrawingImage(drawing);
drawingImage.Freeze();

Image image = new Image();
image.Source = drawingImage;

//Align the image with the top of the bounds of the text geometry
Canvas.SetLeft(image, g.Bounds.Left);
Canvas.SetTop(image, g.Bounds.Top);

layer.AddAdornment(AdornmentPositioningBehavior.TextRelative,
span, null, image, null);
}
}
}


The complete piece of code with the right context can be found here: https://github.com/atlaste/CPPCoverage/blob/master/CoverageExt/CodeRendering/CodeCoverage.cs .

Q: Can someone please tell me how to render the blocks on the background instead of the foreground?

Answer

Asked 7 years ago and still there is next to ZERO info about adornments and extending Visual Studio on the net.

Here is how you do it:

  1. When you create a TextAdornment class instance using VS wizard (for instance: right click on project => Add Item) you receive two files: the first one is the class with the name you picked, and the other one is

    [NameYouPicked]TextViewCreationListener.cs

  2. Find that file in solution explorer and open it.

  3. Go to your adornment definition. It should look like this:
/// <summary>
/// Defines the adornment layer for the adornment. This layer is ordered
/// after the selection layer in the Z-order
/// </summary>
[Export(typeof(AdornmentLayerDefinition))]
[Name("TextAdornment")]
[Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
private AdornmentLayerDefinition editorAdornmentLayer;
  1. As you can see, the order set is AFTER SELECTION. I don't know which layer is the earliest one, but I change the code this way to prevent unwanted collisions:
  [Order(Before = PredefinedAdornmentLayers.BraceCompletion)]
Comments