in src/TimeStampMargin/TimeStampMargin.cs [203:284]
private void UpdateLineNumbers()
{
HashSet<object> visibleLines = new HashSet<object>();
foreach (var line in _textView.TextViewLines)
{
if (line.IsFirstTextViewLineForSnapshotLine)
{
visibleLines.Add(line.IdentityTag);
}
}
//Go backwards through the list so we remove no-longer-visible children back-to-front.
Dictionary<object, TimeStampVisual> visibleTags = new Dictionary<object, TimeStampVisual>();
List<int> childrenToRemove = new List<int>();
for (int i = _translatedCanvas.Children.Count - 1; (i >= 0); --i)
{
TimeStampVisual visual = _translatedCanvas.Children[i] as TimeStampVisual;
if (visual != null)
{
if (visibleLines.Contains(visual.LineTag))
{
visibleTags.Add(visual.LineTag, visual);
}
else
{
childrenToRemove.Add(i);
}
}
else
{
Debug.Fail("Wrong type of child");
}
}
List<TimeStampVisual> newVisuals = new List<TimeStampVisual>();
foreach (var line in _textView.TextViewLines)
{
if (line.IsFirstTextViewLineForSnapshotLine)
{
int lineNumber = line.Start.GetContainingLine().LineNumber;
if (lineNumber < _lineTimeStamps.Count) // No time stamp for the last line in the file.
{
var timeStamp = _lineTimeStamps[lineNumber];
TimeStampVisual visual;
if (!visibleTags.TryGetValue(line.IdentityTag, out visual))
{
int i = childrenToRemove.Count - 1;
if (i < 0)
{
visual = new TimeStampVisual();
newVisuals.Add(visual);
}
else
{
visual = _translatedCanvas.Children[childrenToRemove[i]] as TimeStampVisual;
Debug.Assert(visual != null);
// Don't remove child from canvas.
childrenToRemove.RemoveAt(i);
}
}
// Draw visual on text view.
visual.UpdateVisual(timeStamp, line, _textView, _formatting, base.MinWidth, _oldViewportTop, _showHours, _showMilliseconds);
}
}
}
// Remove all the remaining unused children.
foreach (int i in childrenToRemove)
{
_translatedCanvas.Children.RemoveAt(i);
}
foreach (var visual in newVisuals)
{
_translatedCanvas.Children.Add(visual);
}
}