/// <summary> /// Refresh the adornments of the view based on line /// information from a view layout changed event. /// </summary> /// <typeparam name="TLine">The type representing lines in the view.</typeparam> /// <param name="adornmentView">The view to refresh adornments in.</param> /// <param name="changedLines"> /// The lines that have changed according to a view layout changed /// event.</param> internal static void RefreshAdornments <TLine>(IAdornedTextView <TLine> adornmentView, IReadOnlyList <TLine> changedLines) where TLine : class { // VS2013 and VS2015 Preview under certain circumstances leave // out the first line in runs of lines affected by changes. // // For example when pressing enter on an empty line it removes // the adornment of the empty line, but only sends the newly // created line below in e.NewOrReformattedLines. // // A single call to OnLayoutChanged can contain multiple runs // of affected lines, and each run may be missing a first line // which have been stripped of its previous adornments. foreach (var line in changedLines) { adornmentView.AddAdornmentToLine(line); } var uncertainLinesAbove = changedLines.Select(line => ListItems.PreviousItemOrDefault(adornmentView.Lines, line)).Except(changedLines).Where(line => line != null); foreach (var line in uncertainLinesAbove) { adornmentView.ClearAdornmentsFromLine(line); adornmentView.AddAdornmentToLine(line); } }
private static void AssertAllLinesHaveSingleAdornment(IAdornedTextView <ViewLineStub> adornedTextView) { Action <ViewLineStub> lineMustHaveOneAdornment = line => Assert.Equal(1, line.AdornmentCount); Assert.Collection(adornedTextView.Lines, Enumerable.Repeat(lineMustHaveOneAdornment, 10).ToArray()); }