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 );
}