in XamlControlsGallery/Common/VariedImageSizeLayout.cs [29:85]
protected override Size MeasureOverride(VirtualizingLayoutContext context, Size availableSize)
{
var viewport = context.RealizationRect;
if (availableSize.Width != m_lastAvailableWidth || cachedBoundsInvalid)
{
UpdateCachedBounds(availableSize);
m_lastAvailableWidth = availableSize.Width;
}
// Initialize column offsets
int numColumns = (int)(availableSize.Width / Width);
if (m_columnOffsets.Count == 0)
{
for (int i = 0; i < numColumns; i++)
{
m_columnOffsets.Add(0);
}
}
m_firstIndex = GetStartIndex(viewport);
int currentIndex = m_firstIndex;
double nextOffset = -1.0;
// Measure items from start index to when we hit the end of the viewport.
while (currentIndex < context.ItemCount && nextOffset < viewport.Bottom)
{
var child = context.GetOrCreateElementAt(currentIndex);
child.Measure(new Size(Width, availableSize.Height));
if (currentIndex >= m_cachedBounds.Count)
{
// We do not have bounds for this index. Lay it out and cache it.
int columnIndex = GetIndexOfLowestColumn(m_columnOffsets, out nextOffset);
m_cachedBounds.Add(new Rect(columnIndex * Width, nextOffset, Width, child.DesiredSize.Height));
m_columnOffsets[columnIndex] += child.DesiredSize.Height;
}
else
{
if (currentIndex + 1 == m_cachedBounds.Count)
{
// Last element. Use the next offset.
GetIndexOfLowestColumn(m_columnOffsets, out nextOffset);
}
else
{
nextOffset = m_cachedBounds[currentIndex + 1].Top;
}
}
m_lastIndex = currentIndex;
currentIndex++;
}
var extent = GetExtentSize(availableSize);
return extent;
}