in XamlControlsGallery/Common/WrapPanel.cs [234:302]
protected override Size MeasureOverride(Size constraint)
{
// Variables tracking the size of the current line, the total size
// measured so far, and the maximum size available to fill. Note
// that the line might represent a row or a column depending on the
// orientation.
Orientation o = Orientation;
OrientedSize lineSize = new OrientedSize(o);
OrientedSize totalSize = new OrientedSize(o);
OrientedSize maximumSize = new OrientedSize(o, constraint.Width, constraint.Height);
// Determine the constraints for individual items
double itemWidth = ItemWidth;
double itemHeight = ItemHeight;
bool hasFixedWidth = !double.IsNaN(itemWidth);
bool hasFixedHeight = !double.IsNaN(itemHeight);
Size itemSize = new Size(
hasFixedWidth ? itemWidth : constraint.Width,
hasFixedHeight ? itemHeight : constraint.Height);
// Measure each of the Children
foreach (UIElement element in Children)
{
// Determine the size of the element
element.Measure(itemSize);
OrientedSize elementSize = new OrientedSize(
o,
hasFixedWidth ? itemWidth : element.DesiredSize.Width,
hasFixedHeight ? itemHeight : element.DesiredSize.Height);
// If this element falls of the edge of the line
if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct))
{
// Update the total size with the direct and indirect growth
// for the current line
totalSize.Direct = Math.Max(lineSize.Direct, totalSize.Direct);
totalSize.Indirect += lineSize.Indirect;
// Move the element to a new line
lineSize = elementSize;
// If the current element is larger than the maximum size,
// place it on a line by itself
if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct))
{
// Update the total size for the line occupied by this
// single element
totalSize.Direct = Math.Max(elementSize.Direct, totalSize.Direct);
totalSize.Indirect += elementSize.Indirect;
// Move to a new line
lineSize = new OrientedSize(o);
}
}
else
{
// Otherwise just add the element to the end of the line
lineSize.Direct += elementSize.Direct;
lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect);
}
}
// Update the total size with the elements on the last line
totalSize.Direct = Math.Max(lineSize.Direct, totalSize.Direct);
totalSize.Indirect += lineSize.Indirect;
// Return the total size required as an un-oriented quantity
return new Size(totalSize.Width, totalSize.Height);
}