Row.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using System;
  2. using System.Linq;
  3. using System.Windows;
  4. using System.Windows.Controls;
  5. using HandyControl.Data;
  6. using HandyControl.Tools;
  7. using HandyControl.Tools.Extension;
  8. namespace HandyControl.Controls;
  9. public class Row : Panel
  10. {
  11. private ColLayoutStatus _layoutStatus;
  12. private double _maxChildDesiredHeight;
  13. private double _fixedWidth;
  14. public static readonly DependencyProperty GutterProperty = DependencyProperty.Register(
  15. nameof(Gutter), typeof(double), typeof(Row), new FrameworkPropertyMetadata(
  16. ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsMeasure, null, OnGutterCoerce),
  17. ValidateHelper.IsInRangeOfPosDoubleIncludeZero);
  18. private static object OnGutterCoerce(DependencyObject d, object basevalue) =>
  19. ValidateHelper.IsInRangeOfPosDoubleIncludeZero(basevalue) ? basevalue : .0;
  20. public double Gutter
  21. {
  22. get => (double) GetValue(GutterProperty);
  23. set => SetValue(GutterProperty, value);
  24. }
  25. protected override Size MeasureOverride(Size constraint)
  26. {
  27. var gutter = Gutter;
  28. var totalCellCount = 0;
  29. var totalRowCount = 1;
  30. _fixedWidth = 0;
  31. _maxChildDesiredHeight = 0;
  32. var cols = InternalChildren.OfType<Col>().ToList();
  33. foreach (var child in cols)
  34. {
  35. var cellCount = child.GetLayoutCellCount(_layoutStatus);
  36. if (cellCount == 0 || child.IsFixed)
  37. {
  38. child.Measure(constraint);
  39. _maxChildDesiredHeight = Math.Max(_maxChildDesiredHeight, child.DesiredSize.Height);
  40. _fixedWidth += child.DesiredSize.Width + gutter;
  41. }
  42. }
  43. var itemWidth = (constraint.Width - _fixedWidth + gutter) / ColLayout.ColMaxCellCount;
  44. itemWidth = Math.Max(0, itemWidth);
  45. foreach (var child in cols)
  46. {
  47. var cellCount = child.GetLayoutCellCount(_layoutStatus);
  48. if (cellCount > 0 && !child.IsFixed)
  49. {
  50. totalCellCount += cellCount;
  51. child.Measure(new Size(cellCount * itemWidth - gutter, constraint.Height));
  52. _maxChildDesiredHeight = Math.Max(_maxChildDesiredHeight, child.DesiredSize.Height);
  53. if (totalCellCount > ColLayout.ColMaxCellCount)
  54. {
  55. totalCellCount = cellCount;
  56. totalRowCount++;
  57. }
  58. }
  59. }
  60. return new Size(0, _maxChildDesiredHeight * totalRowCount);
  61. }
  62. protected override Size ArrangeOverride(Size finalSize)
  63. {
  64. var gutter = Gutter;
  65. var totalCellCount = 0;
  66. var cols = InternalChildren.OfType<Col>().ToList();
  67. var itemWidth = (finalSize.Width - _fixedWidth + gutter) / ColLayout.ColMaxCellCount;
  68. itemWidth = Math.Max(0, itemWidth);
  69. var childBounds = new Rect(0, 0, 0, _maxChildDesiredHeight);
  70. _layoutStatus = ColLayout.GetLayoutStatus(finalSize.Width);
  71. foreach (var child in cols)
  72. {
  73. if (!child.IsVisible)
  74. {
  75. continue;
  76. }
  77. var cellCount = child.GetLayoutCellCount(_layoutStatus);
  78. totalCellCount += cellCount;
  79. var childWidth = (cellCount > 0 && !child.IsFixed) ? cellCount * itemWidth - gutter : child.DesiredSize.Width;
  80. childBounds.Width = childWidth;
  81. childBounds.X += child.Offset * itemWidth;
  82. if (totalCellCount > ColLayout.ColMaxCellCount)
  83. {
  84. childBounds.X = 0;
  85. childBounds.Y += _maxChildDesiredHeight;
  86. totalCellCount = cellCount;
  87. }
  88. child.Arrange(childBounds);
  89. childBounds.X += childWidth + gutter;
  90. }
  91. return finalSize;
  92. }
  93. }