diff --git a/src/Compatibility/Core/src/iOS/Resources/StringResources.Designer.cs b/src/Compatibility/Core/src/iOS/Resources/StringResources.Designer.cs index 2975a301ce9b..0fe693d2bf05 100644 --- a/src/Compatibility/Core/src/iOS/Resources/StringResources.Designer.cs +++ b/src/Compatibility/Core/src/iOS/Resources/StringResources.Designer.cs @@ -19,7 +19,7 @@ namespace Microsoft.Maui.Controls.Compatibility.iOS.Resources { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class StringResources { diff --git a/src/Controls/src/Core/HandlerImpl/Layout.Impl.cs b/src/Controls/src/Core/HandlerImpl/Layout.Impl.cs new file mode 100644 index 000000000000..a7d574fcf317 --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/Layout.Impl.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Maui.Controls +{ + public abstract partial class Layout + { + int ICollection.Count => _children.Count; + bool ICollection.IsReadOnly => ((ICollection) _children).IsReadOnly; + public IView this[int index] { get => _children[index]; set => _children[index] = (T)value; } + + void ICollection.Add(IView child) + { + if (child is T view) + { + _children.Add(view); + } + } + + bool ICollection.Remove(IView child) + { + if (child is T view) + { + _children.Remove(view); + return true; + } + + return false; + } + + int IList.IndexOf(IView child) + { + return _children.IndexOf(child); + } + + void IList.Insert(int index, IView child) + { + if (child is T view) + { + _children.Insert(index, view); + } + } + + void IList.RemoveAt(int index) + { + _children.RemoveAt(index); + } + + void ICollection.Clear() + { + _children.Clear(); + } + + bool ICollection.Contains(IView child) + { + return _children.Contains(child); + } + + void ICollection.CopyTo(IView[] array, int arrayIndex) + { + _children.CopyTo(array, arrayIndex); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _children.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _children.GetEnumerator(); + } + } +} diff --git a/src/Controls/src/Core/Layout.cs b/src/Controls/src/Core/Layout.cs index ebd7cf30f7cc..351ea2085742 100644 --- a/src/Controls/src/Core/Layout.cs +++ b/src/Controls/src/Core/Layout.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; @@ -10,11 +11,8 @@ namespace Microsoft.Maui.Controls { [ContentProperty(nameof(Children))] - public abstract class Layout : Layout, Microsoft.Maui.ILayout, IViewContainer where T : View + public abstract partial class Layout : Layout, Microsoft.Maui.ILayout, IViewContainer where T : View { - // TODO ezhart We should look for a way to optimize this a bit - IReadOnlyList Microsoft.Maui.IContainer.Children => Children.ToList(); - readonly ElementCollection _children; protected Layout() => _children = new ElementCollection(InternalChildren); @@ -46,28 +44,10 @@ protected virtual void OnAdded(T view) protected virtual void OnRemoved(T view) { } - - public void Add(IView child) - { - if (child is T view) - { - Children.Add(view); - } - } - - public void Remove(IView child) - { - if (child is T view) - { - Children.Remove(view); - } - } } - public abstract class Layout : View, ILayout, ILayoutController, IPaddingElement, IFrameworkElement, Microsoft.Maui.IContainer + public abstract class Layout : View, ILayout, ILayoutController, IPaddingElement, IFrameworkElement { - IReadOnlyList Microsoft.Maui.IContainer.Children => InternalChildren.OfType().ToList(); - public static readonly BindableProperty IsClippedToBoundsProperty = BindableProperty.Create(nameof(IsClippedToBounds), typeof(bool), typeof(Layout), false); diff --git a/src/Controls/src/Core/Layout/GridLayout.cs b/src/Controls/src/Core/Layout/GridLayout.cs index 8c6a0cd3df54..f1180ae58225 100644 --- a/src/Controls/src/Core/Layout/GridLayout.cs +++ b/src/Controls/src/Core/Layout/GridLayout.cs @@ -231,10 +231,10 @@ public override void Add(IView child) } } - public override void Remove(IView child) + public override bool Remove(IView child) { _viewInfo.Remove(child); - base.Remove(child); + return base.Remove(child); } protected override ILayoutManager CreateLayoutManager() => new GridLayoutManager(this); diff --git a/src/Controls/src/Core/Layout/Layout.cs b/src/Controls/src/Core/Layout/Layout.cs index c7bab8ed7e20..f75741cb6227 100644 --- a/src/Controls/src/Core/Layout/Layout.cs +++ b/src/Controls/src/Core/Layout/Layout.cs @@ -25,11 +25,8 @@ public abstract class Layout : View, Microsoft.Maui.ILayout, IList, IPadd public bool IsReadOnly => ((ICollection)_children).IsReadOnly; - IReadOnlyList IContainer.Children => _children.AsReadOnly(); - public IView this[int index] { get => _children[index]; set => _children[index] = value; } - public Thickness Padding { get => (Thickness)GetValue(PaddingElement.PaddingProperty); @@ -53,56 +50,44 @@ public override SizeRequest GetSizeRequest(double widthConstraint, double height protected override Size MeasureOverride(double widthConstraint, double heightConstraint) { var margin = (this as IView)?.Margin ?? Thickness.Zero; - // Adjust the constraints to account for the margins widthConstraint -= margin.HorizontalThickness; heightConstraint -= margin.VerticalThickness; - var sizeWithoutMargins = LayoutManager.Measure(widthConstraint, heightConstraint); DesiredSize = new Size(sizeWithoutMargins.Width + Margin.HorizontalThickness, sizeWithoutMargins.Height + Margin.VerticalThickness); - return DesiredSize; } - + protected override Size ArrangeOverride(Rectangle bounds) { base.ArrangeOverride(bounds); - Frame = bounds; - LayoutManager.ArrangeChildren(Frame); - foreach (var child in Children) { child.Handler?.NativeArrange(child.Frame); } - return Frame.Size; } protected override void InvalidateMeasureOverride() { base.InvalidateMeasureOverride(); - foreach (var child in Children) { child.InvalidateMeasure(); } } - + public virtual void Add(IView child) { if (child == null) return; - _children.Add(child); - if (child is Element element) element.Parent = this; - InvalidateMeasure(); - LayoutHandler?.Add(child); } @@ -144,12 +129,12 @@ public void Insert(int index, IView child) LayoutHandler?.Add(child); } - public virtual void Remove(IView child) + public virtual bool Remove(IView child) { if (child == null) - return; + return false; - _children.Remove(child); + var result = _children.Remove(child); if (child is Element element) element.Parent = null; @@ -157,6 +142,8 @@ public virtual void Remove(IView child) InvalidateMeasure(); LayoutHandler?.Remove(child); + + return result; } public void RemoveAt(int index) @@ -178,23 +165,6 @@ public void RemoveAt(int index) LayoutHandler?.Remove(child); } - bool ICollection.Remove(IView child) - { - if (child == null) - return false; - - var result = _children.Remove(child); - - if (child is Element element) - element.Parent = null; - - InvalidateMeasure(); - - LayoutHandler?.Remove(child); - - return result; - } - void IPaddingElement.OnPaddingPropertyChanged(Thickness oldValue, Thickness newValue) { InvalidateMeasure(); diff --git a/src/Controls/tests/Core.UnitTests/Layouts/LayoutCompatTests.cs b/src/Controls/tests/Core.UnitTests/Layouts/LayoutCompatTests.cs index dc70ed17dfde..35887b2fb4a9 100644 --- a/src/Controls/tests/Core.UnitTests/Layouts/LayoutCompatTests.cs +++ b/src/Controls/tests/Core.UnitTests/Layouts/LayoutCompatTests.cs @@ -97,7 +97,7 @@ public void GridInsideStackLayout() view.GetDesiredSize(default, default).ReturnsForAnyArgs(expectedSize); label.Handler = view; - stackLayout.Add(grid); + stackLayout.Children.Add(grid); grid.Children.Add(label); contentPage.Content = stackLayout; diff --git a/src/Core/src/Core/IContainer.cs b/src/Core/src/Core/IContainer.cs index 78464bdc331a..3440045d4af8 100644 --- a/src/Core/src/Core/IContainer.cs +++ b/src/Core/src/Core/IContainer.cs @@ -5,11 +5,8 @@ namespace Microsoft.Maui /// /// Provides functionality to act as containers for views. /// - public interface IContainer + public interface IContainer : IList { - /// - /// Gets the collection of children that the Container contains. - /// - IReadOnlyList Children { get; } + } } diff --git a/src/Core/src/Core/ILayout.cs b/src/Core/src/Core/ILayout.cs index b2c373379663..e39f68b7173b 100644 --- a/src/Core/src/Core/ILayout.cs +++ b/src/Core/src/Core/ILayout.cs @@ -13,18 +13,6 @@ public interface ILayout : IView, IContainer /// ILayoutHandler LayoutHandler { get; } - /// - /// Add a child View to the Layout. - /// - /// The child View to add to the Layout. - void Add(IView child); - - /// - /// Remove a child View from the Layout. - /// - /// The child View to remove from the Layout. - void Remove(IView child); - /// /// The space between the outer edge of the ILayout's content area and its children. /// diff --git a/src/Core/src/Handlers/Layout/LayoutHandler.Android.cs b/src/Core/src/Handlers/Layout/LayoutHandler.Android.cs index d215c7047c3a..c4617a65a5ef 100644 --- a/src/Core/src/Handlers/Layout/LayoutHandler.Android.cs +++ b/src/Core/src/Handlers/Layout/LayoutHandler.Android.cs @@ -33,7 +33,7 @@ public override void SetVirtualView(IView view) NativeView.CrossPlatformArrange = VirtualView.Arrange; NativeView.RemoveAllViews(); - foreach (var child in VirtualView.Children) + foreach (var child in VirtualView) { NativeView.AddView(child.ToNative(MauiContext)); } diff --git a/src/Core/src/Handlers/Layout/LayoutHandler.Windows.cs b/src/Core/src/Handlers/Layout/LayoutHandler.Windows.cs index f12be462ce17..6b9972c026cb 100644 --- a/src/Core/src/Handlers/Layout/LayoutHandler.Windows.cs +++ b/src/Core/src/Handlers/Layout/LayoutHandler.Windows.cs @@ -26,7 +26,7 @@ public override void SetVirtualView(IView view) NativeView.CrossPlatformArrange = VirtualView.Arrange; NativeView.Children.Clear(); - foreach (var child in VirtualView.Children) + foreach (var child in VirtualView) { Add(child); } diff --git a/src/Core/src/Handlers/Layout/LayoutHandler.iOS.cs b/src/Core/src/Handlers/Layout/LayoutHandler.iOS.cs index 71538c05c232..40afb7a6cbd2 100644 --- a/src/Core/src/Handlers/Layout/LayoutHandler.iOS.cs +++ b/src/Core/src/Handlers/Layout/LayoutHandler.iOS.cs @@ -40,7 +40,7 @@ public override void SetVirtualView(IView view) child.RemoveFromSuperview(); } - foreach (var child in VirtualView.Children) + foreach (var child in VirtualView) { NativeView.AddSubview(child.ToNative(MauiContext)); } diff --git a/src/Core/src/HotReload/HotReloadExtensions.cs b/src/Core/src/HotReload/HotReloadExtensions.cs index 2a3bd420df49..ba0b9f290bf4 100644 --- a/src/Core/src/HotReload/HotReloadExtensions.cs +++ b/src/Core/src/HotReload/HotReloadExtensions.cs @@ -29,7 +29,7 @@ public static void CheckHandlers(this IView view) if (view is IContainer layout) { - foreach (var v in layout.Children) + foreach (var v in layout) CheckHandlers(v); } } diff --git a/src/Core/src/Layouts/FlexLayoutManager.cs b/src/Core/src/Layouts/FlexLayoutManager.cs index 8c87aef01384..25402d97fc2c 100644 --- a/src/Core/src/Layouts/FlexLayoutManager.cs +++ b/src/Core/src/Layouts/FlexLayoutManager.cs @@ -17,7 +17,7 @@ public void ArrangeChildren(Rectangle childBounds) { FlexLayout.Layout(childBounds.Width, childBounds.Height); - foreach (var child in FlexLayout.Children) + foreach (var child in FlexLayout) { var frame = FlexLayout.GetFlexFrame(child); if (double.IsNaN(frame.X) diff --git a/src/Core/src/Layouts/GridLayoutManager.cs b/src/Core/src/Layouts/GridLayoutManager.cs index c7af1e4dfcd5..b43dc23341a1 100644 --- a/src/Core/src/Layouts/GridLayoutManager.cs +++ b/src/Core/src/Layouts/GridLayoutManager.cs @@ -26,7 +26,7 @@ public override void ArrangeChildren(Rectangle childBounds) { var structure = _gridStructure ?? new GridStructure(Grid, childBounds.Width, childBounds.Height); - foreach (var view in Grid.Children) + foreach (var view in Grid) { if (view.Visibility == Visibility.Collapsed) { @@ -56,7 +56,6 @@ class GridStructure readonly double _columnSpacing; readonly IReadOnlyList _rowDefinitions; readonly IReadOnlyList _columnDefinitions; - readonly IReadOnlyList _gridChildren; readonly Dictionary _spans = new(); @@ -75,7 +74,6 @@ public GridStructure(IGridLayout grid, double widthConstraint, double heightCons _rowSpacing = grid.RowSpacing; _rowDefinitions = grid.RowDefinitions; _columnDefinitions = grid.ColumnDefinitions; - _gridChildren = grid.Children; if (_rowDefinitions.Count == 0) { @@ -112,15 +110,15 @@ public GridStructure(IGridLayout grid, double widthConstraint, double heightCons // We could work out the _childrenToLayOut array (with the Collapsed items filtered out) with a Linq 1-liner // but doing it the hard way means we don't allocate extra enumerators, especially if we're in the // happy path where _none_ of the children are Collapsed. - var gridChildCount = _gridChildren.Count; + var gridChildCount = _grid.Count; _childrenToLayOut = new IView[gridChildCount]; int currentChild = 0; for (int n = 0; n < gridChildCount; n++) { - if (_gridChildren[n].Visibility != Visibility.Collapsed) + if (_grid[n].Visibility != Visibility.Collapsed) { - _childrenToLayOut[currentChild] = _gridChildren[n]; + _childrenToLayOut[currentChild] = _grid[n]; currentChild += 1; } } @@ -429,7 +427,7 @@ void ResolveStars(Definition[] defs, double availableSpace, Func cel if (cellCheck(cell)) // Check whether this cell should count toward the type of star value were measuring { // Update the star width if the view in this cell is bigger - starSize = Math.Max(starSize, dimension(_gridChildren[cell.ViewIndex].DesiredSize)); + starSize = Math.Max(starSize, dimension(_grid[cell.ViewIndex].DesiredSize)); } } } diff --git a/src/Core/src/Layouts/HorizontalStackLayoutManager.cs b/src/Core/src/Layouts/HorizontalStackLayoutManager.cs index 6d156c6d5da4..71ced368b21d 100644 --- a/src/Core/src/Layouts/HorizontalStackLayoutManager.cs +++ b/src/Core/src/Layouts/HorizontalStackLayoutManager.cs @@ -12,15 +12,14 @@ public HorizontalStackLayoutManager(IStackLayout layout) : base(layout) public override Size Measure(double widthConstraint, double heightConstraint) { - var children = Stack.Children; var padding = Stack.Padding; double measuredWidth = 0; double measuredHeight = 0; - for (int n = 0; n < children.Count; n++) + for (int n = 0; n < Stack.Count; n++) { - var child = children[n]; + var child = Stack[n]; if (child.Visibility == Visibility.Collapsed) { @@ -32,7 +31,7 @@ public override Size Measure(double widthConstraint, double heightConstraint) measuredHeight = Math.Max(measuredHeight, measure.Height); } - measuredWidth += MeasureSpacing(Stack.Spacing, children.Count); + measuredWidth += MeasureSpacing(Stack.Spacing, Stack.Count); measuredWidth += padding.HorizontalThickness; measuredHeight += padding.VerticalThickness; @@ -44,23 +43,22 @@ public override Size Measure(double widthConstraint, double heightConstraint) public override void ArrangeChildren(Rectangle bounds) { - var children = Stack.Children; var padding = Stack.Padding; var height = bounds.Height - padding.VerticalThickness; if (Stack.FlowDirection == FlowDirection.LeftToRight) { - ArrangeLeftToRight(height, padding.Left, padding.Top, Stack.Spacing, children); + ArrangeLeftToRight(height, padding.Left, padding.Top, Stack.Spacing, Stack); } else { // We _could_ simply reverse the list of child views when arranging from right to left, // but this way we avoid extra list and enumerator allocations - ArrangeRightToLeft(height, padding.Left, padding.Top, Stack.Spacing, children); + ArrangeRightToLeft(height, padding.Left, padding.Top, Stack.Spacing, Stack); } } - static void ArrangeLeftToRight(double height, double left, double top, double spacing, IReadOnlyList children) + static void ArrangeLeftToRight(double height, double left, double top, double spacing, IList children) { double xPosition = left; @@ -77,7 +75,7 @@ static void ArrangeLeftToRight(double height, double left, double top, double sp } } - static void ArrangeRightToLeft(double height, double left, double top, double spacing, IReadOnlyList children) + static void ArrangeRightToLeft(double height, double left, double top, double spacing, IList children) { double xPostition = left; diff --git a/src/Core/src/Layouts/VerticalStackLayoutManager.cs b/src/Core/src/Layouts/VerticalStackLayoutManager.cs index bcc23ce180d4..21e2e7094c59 100644 --- a/src/Core/src/Layouts/VerticalStackLayoutManager.cs +++ b/src/Core/src/Layouts/VerticalStackLayoutManager.cs @@ -12,15 +12,14 @@ public VerticalStackLayoutManager(IStackLayout stackLayout) : base(stackLayout) public override Size Measure(double widthConstraint, double heightConstraint) { - var children = Stack.Children; var padding = Stack.Padding; double measuredHeight = 0; double measuredWidth = 0; - for (int n = 0; n < children.Count; n++) + for (int n = 0; n < Stack.Count; n++) { - var child = children[n]; + var child = Stack[n]; if (child.Visibility == Visibility.Collapsed) { @@ -32,7 +31,7 @@ public override Size Measure(double widthConstraint, double heightConstraint) measuredWidth = Math.Max(measuredWidth, measure.Width); } - measuredHeight += MeasureSpacing(Stack.Spacing, children.Count); + measuredHeight += MeasureSpacing(Stack.Spacing, Stack.Count); measuredHeight += padding.VerticalThickness; measuredWidth += padding.HorizontalThickness; @@ -50,8 +49,10 @@ public override void ArrangeChildren(Rectangle bounds) double left = padding.Left; double width = bounds.Width - padding.HorizontalThickness; - foreach (var child in Stack.Children) + for (int n = 0; n < Stack.Count; n++) { + var child = Stack[n]; + if (child.Visibility == Visibility.Collapsed) { continue; diff --git a/src/Core/tests/DeviceTests/Handlers/Layout/LayoutHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Layout/LayoutHandlerTests.cs index 511c3e8ef4a6..e2f5a12663af 100644 --- a/src/Core/tests/DeviceTests/Handlers/Layout/LayoutHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Layout/LayoutHandlerTests.cs @@ -13,7 +13,7 @@ public partial class LayoutHandlerTests : HandlerTestBase layout.Children.Count, GetNativeChildCount, 0); + await ValidatePropertyInitValue(layout, () => layout.Count, GetNativeChildCount, 0); } [Fact(DisplayName = "Handler view count matches layout view count")] @@ -24,7 +24,7 @@ public async Task HandlerViewCountMatchesLayoutViewCount() layout.Add(new SliderStub()); layout.Add(new SliderStub()); - await ValidatePropertyInitValue(layout, () => layout.Children.Count, GetNativeChildCount, 2); + await ValidatePropertyInitValue(layout, () => layout.Count, GetNativeChildCount, 2); } [Fact(DisplayName = "Handler removes child from native layout")] diff --git a/src/Core/tests/DeviceTests/Stubs/LayoutStub.cs b/src/Core/tests/DeviceTests/Stubs/LayoutStub.cs index 1ebd50b179ee..2e5ded712014 100644 --- a/src/Core/tests/DeviceTests/Stubs/LayoutStub.cs +++ b/src/Core/tests/DeviceTests/Stubs/LayoutStub.cs @@ -1,13 +1,12 @@ using System; +using System.Collections; using System.Collections.Generic; namespace Microsoft.Maui.DeviceTests.Stubs { public class LayoutStub : StubBase, ILayout { - List _children = new List(); - - public IReadOnlyList Children => _children.AsReadOnly(); + IList _children = new List(); public ILayoutHandler LayoutHandler => Handler as ILayoutHandler; @@ -16,11 +15,55 @@ public void Add(IView child) _children.Add(child); } - public void Remove(IView child) + public bool Remove(IView child) + { + return _children.Remove(child); + } + + public int IndexOf(IView item) + { + return _children.IndexOf(item); + } + + public void Insert(int index, IView item) + { + _children.Insert(index, item); + } + + public void RemoveAt(int index) + { + _children.RemoveAt(index); + } + + public void Clear() { - _children.Remove(child); + _children.Clear(); + } + + public bool Contains(IView item) + { + return _children.Contains(item); + } + + public void CopyTo(IView[] array, int arrayIndex) + { + _children.CopyTo(array, arrayIndex); + } + + public IEnumerator GetEnumerator() + { + return _children.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _children.GetEnumerator(); } public Thickness Padding { get; set; } + public int Count => _children.Count; + public bool IsReadOnly => _children.IsReadOnly; + + public IView this[int index] { get => _children[index]; set => _children[index] = value; } } } diff --git a/src/Core/tests/UnitTests/Layouts/GridLayoutManagerTests.cs b/src/Core/tests/UnitTests/Layouts/GridLayoutManagerTests.cs index 3b8d86927030..fe3acb5c329b 100644 --- a/src/Core/tests/UnitTests/Layouts/GridLayoutManagerTests.cs +++ b/src/Core/tests/UnitTests/Layouts/GridLayoutManagerTests.cs @@ -20,7 +20,7 @@ public class GridLayoutManagerTests const string GridSpan = "GridSpan"; IGridLayout CreateGridLayout(int rowSpacing = 0, int colSpacing = 0, - string rows = null, string columns = null) + string rows = null, string columns = null, IList children = null) { IEnumerable rowDefs = null; IEnumerable colDefs = null; @@ -43,6 +43,11 @@ public class GridLayoutManagerTests SubRowDefs(grid, rowDefs); SubColDefs(grid, colDefs); + if (children != null) + { + SubstituteChildren(grid, children); + } + return grid; } @@ -134,7 +139,7 @@ public void OneAutoRowOneAutoColumn() var view = CreateTestView(new Size(100, 100)); // Set up the grid to have a single child - AddChildren(grid, view); + SubstituteChildren(grid, view); // Set up the row/column values and spans SetLocation(grid, view); @@ -157,7 +162,7 @@ public void TwoAbsoluteColumnsOneAbsoluteRow() var view0 = CreateTestView(viewSize); var view1 = CreateTestView(viewSize); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0); SetLocation(grid, view1, col: 1); @@ -185,7 +190,7 @@ public void TwoAbsoluteRowsAndColumns() var view2 = CreateTestView(viewSize); var view3 = CreateTestView(viewSize); - AddChildren(grid, view0, view1, view2, view3); + SubstituteChildren(grid, view0, view1, view2, view3); SetLocation(grid, view0); SetLocation(grid, view1, col: 1); @@ -225,7 +230,7 @@ public void TwoAbsoluteColumnsOneAutoRow() var view0 = CreateTestView(viewSize); var view1 = CreateTestView(viewSize); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0); SetLocation(grid, view1, col: 1); @@ -251,7 +256,7 @@ public void TwoAbsoluteRowsOneAutoColumn() var view0 = CreateTestView(viewSize); var view1 = CreateTestView(viewSize); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0); SetLocation(grid, view1, row: 1); @@ -272,7 +277,7 @@ public void SingleRowIgnoresRowSpacing() { var grid = CreateGridLayout(rowSpacing: 10); var view = CreateTestView(new Size(100, 100)); - AddChildren(grid, view); + SubstituteChildren(grid, view); SetLocation(grid, view); MeasureAndArrange(grid, double.PositiveInfinity, double.PositiveInfinity); @@ -286,7 +291,7 @@ public void TwoRowsWithSpacing() var grid = CreateGridLayout(rows: "100, 100", rowSpacing: 10); var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0); SetLocation(grid, view1, row: 1); @@ -304,7 +309,7 @@ public void MeasureTwoRowsWithSpacing() var grid = CreateGridLayout(rows: "100, 100", rowSpacing: 10); var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0); SetLocation(grid, view1, row: 1); @@ -322,7 +327,7 @@ public void EmptyAutoRowsHaveNoHeight() var view0 = CreateTestView(new Size(100, 100)); var view2 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0, view2); + SubstituteChildren(grid, view0, view2); SetLocation(grid, view0); SetLocation(grid, view2, row: 2); @@ -345,7 +350,7 @@ public void RowSpacingForEmptyRows() var view0 = CreateTestView(new Size(100, 100)); var view2 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0, view2); + SubstituteChildren(grid, view0, view2); SetLocation(grid, view0); SetLocation(grid, view2, row: 2); @@ -362,7 +367,7 @@ public void SingleColumnIgnoresColumnSpacing() { var grid = CreateGridLayout(colSpacing: 10); var view = CreateTestView(new Size(100, 100)); - AddChildren(grid, view); + SubstituteChildren(grid, view); SetLocation(grid, view); MeasureAndArrange(grid, double.PositiveInfinity, double.PositiveInfinity); @@ -375,7 +380,7 @@ public void TwoColumnsWithSpacing() var grid = CreateGridLayout(columns: "100, 100", colSpacing: 10); var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0); SetLocation(grid, view1, col: 1); @@ -392,7 +397,7 @@ public void MeasureTwoColumnsWithSpacing() var grid = CreateGridLayout(columns: "100, 100", colSpacing: 10); var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0); SetLocation(grid, view1, col: 1); @@ -410,7 +415,7 @@ public void EmptyAutoColumnsHaveNoWidth() var view0 = CreateTestView(new Size(100, 100)); var view2 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0, view2); + SubstituteChildren(grid, view0, view2); SetLocation(grid, view0); SetLocation(grid, view2, col: 2); @@ -433,7 +438,7 @@ public void ColumnSpacingForEmptyColumns() var view0 = CreateTestView(new Size(100, 100)); var view2 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0, view2); + SubstituteChildren(grid, view0, view2); SetLocation(grid, view0); SetLocation(grid, view2, col: 2); @@ -451,7 +456,7 @@ public void ViewSpansRows() { var grid = CreateGridLayout(rows: "auto, auto"); var view0 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0, rowSpan: 2); var measuredSize = MeasureAndArrange(grid); @@ -470,7 +475,7 @@ public void ViewSpansRowsWhenOtherViewsPresent() var grid = CreateGridLayout(rows: "auto, auto", columns: "auto, auto"); var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(50, 50)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0, rowSpan: 2); SetLocation(grid, view1, row: 1, col: 1); @@ -493,7 +498,7 @@ public void RowSpanningShouldAccountForSpacing() var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(50, 50)); var view2 = CreateTestView(new Size(50, 50)); - AddChildren(grid, view0, view1, view2); + SubstituteChildren(grid, view0, view1, view2); SetLocation(grid, view0, rowSpan: 2); SetLocation(grid, view1, row: 0, col: 1); @@ -516,7 +521,7 @@ public void ViewSpansColumnsWhenOtherViewsPresent() var grid = CreateGridLayout(rows: "auto, auto", columns: "auto, auto"); var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(50, 50)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0, colSpan: 2); SetLocation(grid, view1, row: 1, col: 1); @@ -539,7 +544,7 @@ public void ColumnSpanningShouldAccountForSpacing() var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(50, 50)); var view2 = CreateTestView(new Size(50, 50)); - AddChildren(grid, view0, view1, view2); + SubstituteChildren(grid, view0, view1, view2); SetLocation(grid, view0, colSpan: 2); SetLocation(grid, view1, row: 1, col: 0); @@ -562,7 +567,7 @@ public void SmallerSpanningViewsShouldNotAffectRowSize() var grid = CreateGridLayout(rows: "auto, auto", columns: "auto, auto"); var view0 = CreateTestView(new Size(30, 30)); var view1 = CreateTestView(new Size(50, 50)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0, rowSpan: 2); SetLocation(grid, view1, row: 0, col: 1); @@ -583,7 +588,7 @@ public void SmallerSpanningViewsShouldNotAffectColumnSize() var grid = CreateGridLayout(rows: "auto, auto", columns: "auto, auto"); var view0 = CreateTestView(new Size(30, 30)); var view1 = CreateTestView(new Size(50, 50)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0, colSpan: 2); SetLocation(grid, view1, row: 1, col: 0); @@ -603,7 +608,7 @@ public void EmptyAbsoluteRowsAndColumnsAffectSize() { var grid = CreateGridLayout(rows: "10, 40", columns: "15, 85"); var view0 = CreateTestView(new Size(30, 30)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0, row: 1, col: 1); @@ -622,7 +627,7 @@ public void MixedRowAndColumnSpans() var grid = CreateGridLayout(rows: "auto, auto", columns: "auto, auto"); var view0 = CreateTestView(new Size(60, 30)); var view1 = CreateTestView(new Size(30, 60)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0, row: 0, col: 0, colSpan: 2); SetLocation(grid, view1, row: 0, col: 1, rowSpan: 2); @@ -643,7 +648,7 @@ public void RowSpanShouldNotModifyAbsoluteRowSize() var grid = CreateGridLayout(rows: "auto, 20", columns: "auto, auto"); var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(50, 10)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0, rowSpan: 2); SetLocation(grid, view1, row: 1, col: 1); @@ -667,7 +672,7 @@ public void ColumnSpanShouldNotModifyAbsoluteColumnSize() var grid = CreateGridLayout(rows: "auto, auto", columns: "auto, 20"); var view0 = CreateTestView(new Size(100, 100)); var view1 = CreateTestView(new Size(50, 10)); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0, colSpan: 2); SetLocation(grid, view1, row: 1, col: 1); @@ -690,7 +695,7 @@ public void CanSpanAbsoluteColumns() { var grid = CreateGridLayout(rows: "auto", columns: "100,100"); var view0 = CreateTestView(new Size(150, 100)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0, colSpan: 2); var manager = new GridLayoutManager(grid); @@ -708,7 +713,7 @@ public void CanSpanAbsoluteRows() var grid = CreateGridLayout(rows: "100,100", columns: "auto"); var view0 = CreateTestView(new Size(100, 150)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0, rowSpan: 2); var manager = new GridLayoutManager(grid); @@ -729,7 +734,7 @@ public void SingleStarColumn() var grid = CreateGridLayout(rows: "auto", columns: $"*"); var view0 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0); MeasureAndArrange(grid, screenWidth, screenHeight); @@ -749,7 +754,7 @@ public void SingleWeightedStarColumn() var grid = CreateGridLayout(rows: "auto", columns: $"3*"); var view0 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0); MeasureAndArrange(grid, screenWidth, screenHeight); @@ -772,7 +777,7 @@ public void MultipleStarColumns() var view1 = CreateTestView(viewSize); var view2 = CreateTestView(viewSize); - AddChildren(grid, view0, view1, view2); + SubstituteChildren(grid, view0, view1, view2); SetLocation(grid, view0); SetLocation(grid, view1, col: 1); @@ -807,7 +812,7 @@ public void WeightedStarColumn() var view0 = CreateTestView(viewSize); var view1 = CreateTestView(viewSize); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0); SetLocation(grid, view1, col: 1); @@ -841,7 +846,7 @@ public void StarColumnWithViewInfiniteWidthMeasure() var grid = CreateGridLayout(rows: "auto", columns: $"*"); var view0 = CreateTestView(new Size(100, 50)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0); var manager = new GridLayoutManager(grid); @@ -860,7 +865,7 @@ public void MultipleStarColumnsWithViewsInfiniteWidthMeasure() var view1 = CreateTestView(new Size(75, 50)); var view2 = CreateTestView(new Size(50, 50)); - AddChildren(grid, view0, view1, view2); + SubstituteChildren(grid, view0, view1, view2); SetLocation(grid, view0); SetLocation(grid, view1, col: 1); @@ -886,7 +891,7 @@ public void SingleStarRow() var grid = CreateGridLayout(rows: "*", columns: "auto"); var view0 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0); MeasureAndArrange(grid, screenWidth, screenHeight); @@ -906,7 +911,7 @@ public void SingleWeightedStarRow() var grid = CreateGridLayout(rows: "3*", columns: "auto"); var view0 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0); MeasureAndArrange(grid, screenWidth, screenHeight); @@ -929,7 +934,7 @@ public void MultipleStarRows() var view1 = CreateTestView(viewSize); var view2 = CreateTestView(viewSize); - AddChildren(grid, view0, view1, view2); + SubstituteChildren(grid, view0, view1, view2); SetLocation(grid, view0); SetLocation(grid, view1, row: 1); @@ -958,7 +963,7 @@ public void WeightedStarRow() var view0 = CreateTestView(viewSize); var view1 = CreateTestView(viewSize); - AddChildren(grid, view0, view1); + SubstituteChildren(grid, view0, view1); SetLocation(grid, view0); SetLocation(grid, view1, row: 1); @@ -992,7 +997,7 @@ public void StarRowWithViewInfiniteHeightMeasure() var grid = CreateGridLayout(rows: "*", columns: $"auto"); var view0 = CreateTestView(new Size(100, 50)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0); var manager = new GridLayoutManager(grid); @@ -1011,7 +1016,7 @@ public void MultipleStarRowsWithViewsInfiniteHeightMeasure() var view1 = CreateTestView(new Size(50, 75)); var view2 = CreateTestView(new Size(50, 50)); - AddChildren(grid, view0, view1, view2); + SubstituteChildren(grid, view0, view1, view2); SetLocation(grid, view0); SetLocation(grid, view1, row: 1); @@ -1041,7 +1046,7 @@ public void MixStarsAndExplicitSizes() var view1 = CreateTestView(viewSize); var view2 = CreateTestView(viewSize); - AddChildren(grid, view0, view1, view2); + SubstituteChildren(grid, view0, view1, view2); SetLocation(grid, view0); SetLocation(grid, view1, col: 1); @@ -1066,7 +1071,7 @@ public void UsesImpliedRowAndColumnIfNothingDefined() { var grid = CreateGridLayout(); var view0 = CreateTestView(new Size(100, 100)); - AddChildren(grid, view0); + SubstituteChildren(grid, view0); SetLocation(grid, view0); // Using 300,300 - the implied row/column are GridLength.Star @@ -1079,14 +1084,11 @@ public void UsesImpliedRowAndColumnIfNothingDefined() [Fact] public void IgnoresCollapsedViews() { - var grid = CreateGridLayout(); - var view = LayoutTestHelpers.CreateTestView(new Size(100, 100)); var collapsedView = LayoutTestHelpers.CreateTestView(new Size(100, 100)); collapsedView.Visibility.Returns(Visibility.Collapsed); - var children = new List() { view, collapsedView }.AsReadOnly(); - grid.Children.Returns(children); + var grid = CreateGridLayout(children: new List() { view, collapsedView }); var manager = new GridLayoutManager(grid); var measure = manager.Measure(100, double.PositiveInfinity); @@ -1104,14 +1106,11 @@ public void IgnoresCollapsedViews() [Fact] public void DoesNotIgnoreHiddenViews() { - var grid = CreateGridLayout(); - var view = LayoutTestHelpers.CreateTestView(new Size(100, 100)); var hiddenView = LayoutTestHelpers.CreateTestView(new Size(100, 100)); hiddenView.Visibility.Returns(Visibility.Hidden); - var children = new List() { view, hiddenView }.AsReadOnly(); - grid.Children.Returns(children); + var grid = CreateGridLayout(children: new List() { view, hiddenView }); var manager = new GridLayoutManager(grid); var measure = manager.Measure(100, double.PositiveInfinity); @@ -1130,7 +1129,7 @@ IGridLayout BuildPaddedGrid(Thickness padding, double viewWidth, double viewHeig { var grid = CreateGridLayout(); var view = CreateTestView(new Size(viewWidth, viewHeight)); - AddChildren(grid, view); + SubstituteChildren(grid, view); SetLocation(grid, view); grid.Padding.Returns(padding); @@ -1180,7 +1179,7 @@ public void ArrangeAccountsForPadding(double left, double top, double right, dou var measuredSize = manager.Measure(double.PositiveInfinity, double.PositiveInfinity); manager.ArrangeChildren(new Rectangle(Point.Zero, measuredSize)); - AssertArranged(grid.Children[0], padding.Left, padding.Top, viewWidth, viewHeight); + AssertArranged(grid[0], padding.Left, padding.Top, viewWidth, viewHeight); } } } diff --git a/src/Core/tests/UnitTests/Layouts/HorizontalStackLayoutManagerTests.cs b/src/Core/tests/UnitTests/Layouts/HorizontalStackLayoutManagerTests.cs index 260f2704b3b5..7f8c5aa35f29 100644 --- a/src/Core/tests/UnitTests/Layouts/HorizontalStackLayoutManagerTests.cs +++ b/src/Core/tests/UnitTests/Layouts/HorizontalStackLayoutManagerTests.cs @@ -43,7 +43,7 @@ public void SpacingArrangementOneItem(int spacing) manager.ArrangeChildren(new Rectangle(Point.Zero, measuredSize)); var expectedRectangle = new Rectangle(0, 0, 100, 100); - stack.Children[0].Received().Arrange(Arg.Is(expectedRectangle)); + stack[0].Received().Arrange(Arg.Is(expectedRectangle)); } [Theory("Spacing should affect arrangement with more than one item")] @@ -59,10 +59,10 @@ public void SpacingArrangementTwoItems(int spacing) manager.ArrangeChildren(new Rectangle(Point.Zero, measuredSize)); var expectedRectangle0 = new Rectangle(0, 0, 100, 100); - stack.Children[0].Received().Arrange(Arg.Is(expectedRectangle0)); + stack[0].Received().Arrange(Arg.Is(expectedRectangle0)); var expectedRectangle1 = new Rectangle(100 + spacing, 0, 100, 100); - stack.Children[1].Received().Arrange(Arg.Is(expectedRectangle1)); + stack[1].Received().Arrange(Arg.Is(expectedRectangle1)); } [Theory] @@ -71,13 +71,9 @@ public void SpacingArrangementTwoItems(int spacing) [InlineData(1250, -1, 1250)] public void StackAppliesWidth(double viewWidth, double stackWidth, double expectedWidth) { - var stack = CreateTestLayout(); - var view = LayoutTestHelpers.CreateTestView(new Size(viewWidth, 100)); - var children = new List() { view }.AsReadOnly(); - - stack.Children.Returns(children); + var stack = CreateTestLayout(new List() { view }); stack.Width.Returns(stackWidth); var manager = new HorizontalStackLayoutManager(stack); @@ -100,8 +96,8 @@ public void LtrShouldHaveFirstItemOnTheLeft() var expectedRectangle0 = new Rectangle(0, 0, 100, 100); var expectedRectangle1 = new Rectangle(100, 0, 100, 100); - stack.Children[0].Received().Arrange(Arg.Is(expectedRectangle0)); - stack.Children[1].Received().Arrange(Arg.Is(expectedRectangle1)); + stack[0].Received().Arrange(Arg.Is(expectedRectangle0)); + stack[1].Received().Arrange(Arg.Is(expectedRectangle1)); } [Fact(DisplayName = "First View in RTL Horizontal Stack is on the right")] @@ -119,21 +115,18 @@ public void RtlShouldHaveFirstItemOnTheRight() var expectedRectangle0 = new Rectangle(100, 0, 100, 100); var expectedRectangle1 = new Rectangle(0, 0, 100, 100); - stack.Children[0].Received().Arrange(Arg.Is(expectedRectangle0)); - stack.Children[1].Received().Arrange(Arg.Is(expectedRectangle1)); + stack[0].Received().Arrange(Arg.Is(expectedRectangle0)); + stack[1].Received().Arrange(Arg.Is(expectedRectangle1)); } [Fact] public void IgnoresCollapsedViews() { - var stack = CreateTestLayout(); - var view = LayoutTestHelpers.CreateTestView(new Size(100, 100)); var collapsedView = LayoutTestHelpers.CreateTestView(new Size(100, 100)); collapsedView.Visibility.Returns(Visibility.Collapsed); - var children = new List() { view, collapsedView }.AsReadOnly(); - stack.Children.Returns(children); + var stack = CreateTestLayout(new List() { view, collapsedView }); var manager = new HorizontalStackLayoutManager(stack); var measure = manager.Measure(double.PositiveInfinity, 100); @@ -151,14 +144,11 @@ public void IgnoresCollapsedViews() [Fact] public void DoesNotIgnoreHiddenViews() { - var stack = CreateTestLayout(); - var view = LayoutTestHelpers.CreateTestView(new Size(100, 100)); var hiddenView = LayoutTestHelpers.CreateTestView(new Size(100, 100)); hiddenView.Visibility.Returns(Visibility.Hidden); - var children = new List() { view, hiddenView }.AsReadOnly(); - stack.Children.Returns(children); + var stack = CreateTestLayout(new List() { view, hiddenView }); var manager = new HorizontalStackLayoutManager(stack); var measure = manager.Measure(double.PositiveInfinity, 100); @@ -222,7 +212,7 @@ public void ArrangeAccountsForPadding(double left, double top, double right, dou var measuredSize = manager.Measure(double.PositiveInfinity, double.PositiveInfinity); manager.ArrangeChildren(new Rectangle(Point.Zero, measuredSize)); - AssertArranged(stack.Children[0], padding.Left, padding.Top, viewWidth, viewHeight); + AssertArranged(stack[0], padding.Left, padding.Top, viewWidth, viewHeight); } } } diff --git a/src/Core/tests/UnitTests/Layouts/LayoutTestHelpers.cs b/src/Core/tests/UnitTests/Layouts/LayoutTestHelpers.cs index 5971e5dad54c..7503ee1410af 100644 --- a/src/Core/tests/UnitTests/Layouts/LayoutTestHelpers.cs +++ b/src/Core/tests/UnitTests/Layouts/LayoutTestHelpers.cs @@ -26,10 +26,18 @@ public static IView CreateTestView(Size viewSize) return view; } - public static void AddChildren(ILayout layout, params IView[] views) + public static void SubstituteChildren(ILayout layout, params IView[] views) { var children = new List(views); - layout.Children.Returns(children.AsReadOnly()); + + SubstituteChildren(layout, children); + } + + public static void SubstituteChildren(ILayout layout, IList children) + { + layout[Arg.Any()].Returns(args => children[(int)args[0]]); + layout.GetEnumerator().Returns(children.GetEnumerator()); + layout.Count.Returns(children.Count); } public static void AssertArranged(IView view, double x, double y, double width, double height) diff --git a/src/Core/tests/UnitTests/Layouts/StackLayoutManagerTests.cs b/src/Core/tests/UnitTests/Layouts/StackLayoutManagerTests.cs index 81e336ae7c30..d3f284a6358f 100644 --- a/src/Core/tests/UnitTests/Layouts/StackLayoutManagerTests.cs +++ b/src/Core/tests/UnitTests/Layouts/StackLayoutManagerTests.cs @@ -2,6 +2,7 @@ using Microsoft.Maui; using Microsoft.Maui.Graphics; using NSubstitute; +using static Microsoft.Maui.UnitTests.Layouts.LayoutTestHelpers; namespace Microsoft.Maui.UnitTests.Layouts { @@ -17,6 +18,13 @@ protected IStackLayout CreateTestLayout() return stack; } + protected IStackLayout CreateTestLayout(IList children) + { + var stack = CreateTestLayout(); + SubstituteChildren(stack, children); + return stack; + } + protected IView CreateTestView() { var view = Substitute.For(); @@ -51,7 +59,7 @@ protected IStackLayout BuildStack(int viewCount, double viewWidth, double viewHe children.Add(view); } - stack.Children.Returns(children.AsReadOnly()); + SubstituteChildren(stack, children); return stack; } diff --git a/src/Core/tests/UnitTests/Layouts/VerticalStackLayoutManagerTests.cs b/src/Core/tests/UnitTests/Layouts/VerticalStackLayoutManagerTests.cs index cbc1dc061001..14cf6caa9305 100644 --- a/src/Core/tests/UnitTests/Layouts/VerticalStackLayoutManagerTests.cs +++ b/src/Core/tests/UnitTests/Layouts/VerticalStackLayoutManagerTests.cs @@ -41,7 +41,7 @@ public void SpacingArrangementOneItem(int spacing) manager.ArrangeChildren(new Rectangle(Point.Zero, measuredSize)); var expectedRectangle = new Rectangle(0, 0, 100, 100); - stack.Children[0].Received().Arrange(Arg.Is(expectedRectangle)); + stack[0].Received().Arrange(Arg.Is(expectedRectangle)); } [Theory("Spacing has an effect when there's more than one item")] @@ -56,8 +56,8 @@ public void SpacingArrangementTwoItems(int spacing) var measuredSize = manager.Measure(double.PositiveInfinity, 100); manager.ArrangeChildren(new Rectangle(Point.Zero, measuredSize)); - AssertArranged(stack.Children[0], 0, 0, 100, 100); - AssertArranged(stack.Children[1], 0, 100 + spacing, 100, 100); + AssertArranged(stack[0], 0, 0, 100, 100); + AssertArranged(stack[1], 0, 100 + spacing, 100, 100); } [Theory] @@ -66,13 +66,10 @@ public void SpacingArrangementTwoItems(int spacing) [InlineData(1250, -1, 1250)] public void StackAppliesHeight(double viewHeight, double stackHeight, double expectedHeight) { - var stack = CreateTestLayout(); - var view = LayoutTestHelpers.CreateTestView(new Size(100, viewHeight)); - var children = new List() { view }.AsReadOnly(); + var stack = CreateTestLayout(new List() { view }); - stack.Children.Returns(children); stack.Height.Returns(stackHeight); var manager = new VerticalStackLayoutManager(stack); @@ -83,14 +80,11 @@ public void StackAppliesHeight(double viewHeight, double stackHeight, double exp [Fact] public void IgnoresCollapsedViews() { - var stack = CreateTestLayout(); - var view = LayoutTestHelpers.CreateTestView(new Size(100, 100)); var collapsedView = LayoutTestHelpers.CreateTestView(new Size(100, 100)); collapsedView.Visibility.Returns(Visibility.Collapsed); - var children = new List() { view, collapsedView }.AsReadOnly(); - stack.Children.Returns(children); + var stack = CreateTestLayout(new List() { view, collapsedView }); var manager = new VerticalStackLayoutManager(stack); var measure = manager.Measure(100, double.PositiveInfinity); @@ -108,14 +102,11 @@ public void IgnoresCollapsedViews() [Fact] public void DoesNotIgnoreHiddenViews() { - var stack = CreateTestLayout(); - var view = LayoutTestHelpers.CreateTestView(new Size(100, 100)); var hiddenView = LayoutTestHelpers.CreateTestView(new Size(100, 100)); hiddenView.Visibility.Returns(Visibility.Hidden); - var children = new List() { view, hiddenView }.AsReadOnly(); - stack.Children.Returns(children); + var stack = CreateTestLayout(new List() { view, hiddenView }); var manager = new VerticalStackLayoutManager(stack); var measure = manager.Measure(100, double.PositiveInfinity); @@ -179,7 +170,7 @@ public void ArrangeAccountsForPadding(double left, double top, double right, dou var measuredSize = manager.Measure(double.PositiveInfinity, double.PositiveInfinity); manager.ArrangeChildren(new Rectangle(Point.Zero, measuredSize)); - AssertArranged(stack.Children[0], padding.Left, padding.Top, viewWidth, viewHeight); + AssertArranged(stack[0], padding.Left, padding.Top, viewWidth, viewHeight); } } }