using System; using System.Linq; using System.Windows; using System.Windows.Controls; using HandyControl.Data; using HandyControl.Tools; using HandyControl.Tools.Extension; namespace HandyControl.Controls; public class Row : Panel { private ColLayoutStatus _layoutStatus; private double _maxChildDesiredHeight; private double _fixedWidth; public static readonly DependencyProperty GutterProperty = DependencyProperty.Register( nameof(Gutter), typeof(double), typeof(Row), new FrameworkPropertyMetadata( ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsMeasure, null, OnGutterCoerce), ValidateHelper.IsInRangeOfPosDoubleIncludeZero); private static object OnGutterCoerce(DependencyObject d, object basevalue) => ValidateHelper.IsInRangeOfPosDoubleIncludeZero(basevalue) ? basevalue : .0; public double Gutter { get => (double) GetValue(GutterProperty); set => SetValue(GutterProperty, value); } protected override Size MeasureOverride(Size constraint) { var gutter = Gutter; var totalCellCount = 0; var totalRowCount = 1; _fixedWidth = 0; _maxChildDesiredHeight = 0; var cols = InternalChildren.OfType().ToList(); foreach (var child in cols) { var cellCount = child.GetLayoutCellCount(_layoutStatus); if (cellCount == 0 || child.IsFixed) { child.Measure(constraint); _maxChildDesiredHeight = Math.Max(_maxChildDesiredHeight, child.DesiredSize.Height); _fixedWidth += child.DesiredSize.Width + gutter; } } var itemWidth = (constraint.Width - _fixedWidth + gutter) / ColLayout.ColMaxCellCount; itemWidth = Math.Max(0, itemWidth); foreach (var child in cols) { var cellCount = child.GetLayoutCellCount(_layoutStatus); if (cellCount > 0 && !child.IsFixed) { totalCellCount += cellCount; child.Measure(new Size(cellCount * itemWidth - gutter, constraint.Height)); _maxChildDesiredHeight = Math.Max(_maxChildDesiredHeight, child.DesiredSize.Height); if (totalCellCount > ColLayout.ColMaxCellCount) { totalCellCount = cellCount; totalRowCount++; } } } return new Size(0, _maxChildDesiredHeight * totalRowCount); } protected override Size ArrangeOverride(Size finalSize) { var gutter = Gutter; var totalCellCount = 0; var cols = InternalChildren.OfType().ToList(); var itemWidth = (finalSize.Width - _fixedWidth + gutter) / ColLayout.ColMaxCellCount; itemWidth = Math.Max(0, itemWidth); var childBounds = new Rect(0, 0, 0, _maxChildDesiredHeight); _layoutStatus = ColLayout.GetLayoutStatus(finalSize.Width); foreach (var child in cols) { if (!child.IsVisible) { continue; } var cellCount = child.GetLayoutCellCount(_layoutStatus); totalCellCount += cellCount; var childWidth = (cellCount > 0 && !child.IsFixed) ? cellCount * itemWidth - gutter : child.DesiredSize.Width; childBounds.Width = childWidth; childBounds.X += child.Offset * itemWidth; if (totalCellCount > ColLayout.ColMaxCellCount) { childBounds.X = 0; childBounds.Y += _maxChildDesiredHeight; totalCellCount = cellCount; } child.Arrange(childBounds); childBounds.X += childWidth + gutter; } return finalSize; } }