/// <summary> /// Implements custom measure logic. /// </summary> /// <param name="constraint">Constraint to measure within.</param> /// <returns>Desired size.</returns> protected override Size MeasureOverride(Size constraint) { var bands = Bands; var orientation = Orientation; // Calculate the Size to Measure children with var constrainedLength = new OrientedLength(orientation, constraint); constrainedLength.PrimaryLength = double.PositiveInfinity; constrainedLength.SecondaryLength /= bands; var availableLength = constrainedLength.Size; // Measure each child var band = 0; var levelLength = new OrientedLength(orientation); var usedLength = new OrientedLength(orientation); foreach (UIElement child in Children) { child.Measure(availableLength); // Update for the band/level of this child var desiredLength = new OrientedLength(orientation, child.DesiredSize); levelLength.PrimaryLength = Math.Max(levelLength.PrimaryLength, desiredLength.PrimaryLength); levelLength.SecondaryLength += desiredLength.SecondaryLength; // Move to the next band band = (band + 1) % bands; if (0 == band) { // Update for the complete level; reset for the next one usedLength.PrimaryLength += levelLength.PrimaryLength; usedLength.SecondaryLength = Math.Max(usedLength.SecondaryLength, levelLength.SecondaryLength); levelLength.PrimaryLength = 0; levelLength.SecondaryLength = 0; } } // Update for the partial level at the end usedLength.PrimaryLength += levelLength.PrimaryLength; usedLength.SecondaryLength = Math.Max(usedLength.SecondaryLength, levelLength.SecondaryLength); // Return the used size return usedLength.Size; }
/// <summary> /// Implements custom arrange logic. /// </summary> /// <param name="arrangeSize">Size to arrange to.</param> /// <returns>Used size.</returns> protected override Size ArrangeOverride(Size arrangeSize) { var bands = Bands; var orientation = Orientation; var count = Children.Count; // Prepare the Rect to arrange children with var arrangeLength = new OrientedLength(orientation, arrangeSize); arrangeLength.SecondaryLength /= bands; // Arrange each child for (var i = 0; i < count; i += bands) { // Determine the length of the current level arrangeLength.PrimaryLength = 0; arrangeLength.SecondaryOffset = 0; for (var band = 0; (band < bands) && (i + band < count); band++) { var desiredLength = new OrientedLength(orientation, Children[i + band].DesiredSize); arrangeLength.PrimaryLength = Math.Max(arrangeLength.PrimaryLength, desiredLength.PrimaryLength); } // Arrange each band within the level for (var band = 0; (band < bands) && (i + band < count); band++) { Children[i + band].Arrange(arrangeLength.Rect); arrangeLength.SecondaryOffset += arrangeLength.SecondaryLength; } // Update for the next level arrangeLength.PrimaryOffset += arrangeLength.PrimaryLength; } // Return the arranged size return arrangeSize; }