diff --git a/src/Avalonia.Controls/Grid.cs b/src/Avalonia.Controls/Grid.cs
index 0a55a44ad2..7d30a7e923 100644
--- a/src/Avalonia.Controls/Grid.cs
+++ b/src/Avalonia.Controls/Grid.cs
@@ -448,7 +448,7 @@ namespace Avalonia.Controls
MeasureCellsGroup(extData.CellGroup1, constraint, false, false);
double combinedRowSpacing = RowSpacing * (RowDefinitions.Count - 1);
double combinedColumnSpacing = ColumnSpacing * (ColumnDefinitions.Count - 1);
- Size innerAvailableSize = new Size(constraint.Width - combinedRowSpacing, constraint.Height - combinedColumnSpacing);
+ Size innerAvailableSize = new Size(constraint.Width - combinedColumnSpacing, constraint.Height - combinedRowSpacing);
{
// after Group1 is measured, only Group3 may have cells belonging to Auto rows.
bool canResolveStarsV = !HasGroup3CellsInAutoRows;
@@ -512,8 +512,8 @@ namespace Avalonia.Controls
MeasureCellsGroup(extData.CellGroup4, constraint, false, false);
gridDesiredSize = new Size(
- CalculateDesiredSize(DefinitionsU) + ColumnSpacing * (DefinitionsU.Count - 1),
- CalculateDesiredSize(DefinitionsV) + RowSpacing * (DefinitionsU.Count - 1));
+ CalculateDesiredSize(DefinitionsU) + ColumnSpacing * (DefinitionsU.Count - 1),
+ CalculateDesiredSize(DefinitionsV) + RowSpacing * (DefinitionsU.Count - 1));
}
}
finally
@@ -566,11 +566,10 @@ namespace Avalonia.Controls
int rowSpan = PrivateCells[currentCell].RowSpan;
Rect cellRect = new Rect(
- columnIndex == 0 ? 0.0 : DefinitionsU[columnIndex].FinalOffset + (columnSpacing * columnIndex),
- rowIndex == 0 ? 0.0 : DefinitionsV[rowIndex].FinalOffset + (rowSpacing * rowIndex),
- GetFinalSizeForRange(DefinitionsU, columnIndex, columnSpan),
- GetFinalSizeForRange(DefinitionsV, rowIndex, rowSpan));
-
+ columnIndex == 0 ? 0d : DefinitionsU[columnIndex].FinalOffset,
+ rowIndex == 0 ? 0d : DefinitionsV[rowIndex].FinalOffset,
+ GetFinalSizeForRange(DefinitionsU, columnIndex, columnSpan, columnSpacing),
+ GetFinalSizeForRange(DefinitionsV, rowIndex, rowSpan, rowSpacing));
cell.Arrange(cellRect);
}
@@ -1132,9 +1131,10 @@ namespace Avalonia.Controls
{
// otherwise...
cellMeasureWidth = GetMeasureSizeForRange(
- DefinitionsU,
- PrivateCells[cell].ColumnIndex,
- PrivateCells[cell].ColumnSpan);
+ DefinitionsU,
+ PrivateCells[cell].ColumnIndex,
+ PrivateCells[cell].ColumnSpan,
+ ColumnSpacing);
}
if (forceInfinityV)
@@ -1152,9 +1152,10 @@ namespace Avalonia.Controls
else
{
cellMeasureHeight = GetMeasureSizeForRange(
- DefinitionsV,
- PrivateCells[cell].RowIndex,
- PrivateCells[cell].RowSpan);
+ DefinitionsV,
+ PrivateCells[cell].RowIndex,
+ PrivateCells[cell].RowSpan,
+ RowSpacing);
}
@@ -1169,6 +1170,7 @@ namespace Avalonia.Controls
/// Source array of definitions to read values from.
/// Starting index of the range.
/// Number of definitions included in the range.
+ /// or
/// Calculated measure size.
///
/// For "Auto" definitions MinWidth is used in place of PreferredSize.
@@ -1176,21 +1178,24 @@ namespace Avalonia.Controls
private static double GetMeasureSizeForRange(
IReadOnlyList definitions,
int start,
- int count)
+ int count,
+ double spacing)
{
Debug.Assert(0 < count && 0 <= start && (start + count) <= definitions.Count);
- double measureSize = 0;
+ double measureSize = -spacing;
int i = start + count - 1;
do
{
- measureSize += (definitions[i].SizeType == LayoutTimeSizeType.Auto)
- ? definitions[i].MinSize
- : definitions[i].MeasureSize;
+ measureSize +=
+ spacing +
+ (definitions[i].SizeType == LayoutTimeSizeType.Auto ?
+ definitions[i].MinSize :
+ definitions[i].MeasureSize);
} while (--i >= start);
- return (measureSize);
+ return measureSize;
}
///
@@ -2216,11 +2221,12 @@ namespace Avalonia.Controls
}
}
+ double spacing = columns ? ColumnSpacing : RowSpacing;
// Phase 6. Compute final offsets
definitions[0].FinalOffset = 0.0;
for (int i = 0; i < definitions.Count; ++i)
{
- definitions[(i + 1) % definitions.Count].FinalOffset = definitions[i].FinalOffset + definitions[i].SizeCache;
+ definitions[(i + 1) % definitions.Count].FinalOffset = definitions[i].FinalOffset + definitions[i].SizeCache + spacing;
}
}
@@ -2296,21 +2302,23 @@ namespace Avalonia.Controls
/// Array of definitions to process.
/// Start of the range.
/// Number of items in the range.
+ /// or
/// Final size.
private static double GetFinalSizeForRange(
IReadOnlyList definitions,
int start,
- int count)
+ int count,
+ double spacing)
{
- double size = 0;
+ double size = -spacing;
int i = start + count - 1;
do
{
- size += definitions[i].SizeCache;
+ size += spacing + definitions[i].SizeCache;
} while (--i >= start);
- return (size);
+ return size;
}
///
diff --git a/tests/Avalonia.Controls.UnitTests/GridTests.cs b/tests/Avalonia.Controls.UnitTests/GridTests.cs
index 3eebdde255..8633aeed5c 100644
--- a/tests/Avalonia.Controls.UnitTests/GridTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/GridTests.cs
@@ -1741,6 +1741,48 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(new Rect(90, 90, 30, 30), target.Children[3].Bounds);
}
+ [Fact]
+ public void Should_Grid_Controls_With_Spacing_Overflow2()
+ {
+ var target = new Grid
+ {
+ Height = 100,
+ ColumnSpacing = 20,
+ ColumnDefinitions = ColumnDefinitions.Parse("*,Auto"),
+ Children =
+ {
+ new Border { Width = 60 },
+ new Border { [Grid.ColumnProperty] = 1, Width = 60 }
+ },
+ };
+ target.Measure(new Size(100, 100));
+ target.Arrange(new Rect(target.DesiredSize));
+
+ Assert.Equal(new Rect(0, 0, 100, 100), target.Bounds);
+ Assert.Equal(new Rect(-20, 0, 60, 100), target.Children[0].Bounds);
+ Assert.Equal(new Rect(40, 0, 60, 100), target.Children[1].Bounds);
+ }
+
+ [Fact]
+ public void Grid_Controls_With_Spacing_With_Span()
+ {
+ var target = new Grid
+ {
+ Height = 100,
+ ColumnSpacing = 20,
+ ColumnDefinitions = ColumnDefinitions.Parse("20,20"),
+ Children =
+ {
+ new Border { [Grid.ColumnSpanProperty] = 2 }
+ },
+ };
+ target.Measure(new Size(100, 100));
+ target.Arrange(new Rect(target.DesiredSize));
+
+ Assert.Equal(new Rect(0, 0, 60, 100), target.Bounds);
+ Assert.Equal(new Rect(0, 0, 60, 100), target.Children[0].Bounds);
+ }
+
private class TestControl : Control
{
public Size MeasureSize { get; set; }