diff --git a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs b/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs
index 8a21d7aa4b..5ff0fd1feb 100644
--- a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs
+++ b/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs
@@ -25,7 +25,7 @@ namespace Avalonia.Controls.Embedding
{
EnsureInitialized();
ApplyTemplate();
- LayoutManager.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass();
}
private void EnsureInitialized()
diff --git a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs
index d326ab5734..b037dd9901 100644
--- a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs
+++ b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs
@@ -18,7 +18,7 @@ namespace Avalonia.Controls.Embedding.Offscreen
{
EnsureInitialized();
ApplyTemplate();
- LayoutManager.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass();
}
private void EnsureInitialized()
diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs
index c5491746a3..6c3a2d4a03 100644
--- a/src/Avalonia.Controls/TopLevel.cs
+++ b/src/Avalonia.Controls/TopLevel.cs
@@ -318,7 +318,7 @@ namespace Avalonia.Controls
///
/// Creates the layout manager for this .
///
- protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager();
+ protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager(this);
///
/// Handles a paint notification from .
@@ -351,6 +351,7 @@ namespace Avalonia.Controls
OnClosed(EventArgs.Empty);
Renderer?.Dispose();
Renderer = null;
+ LayoutManager?.Dispose();
}
///
diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs
index ff7cc41e3b..cedd20ace5 100644
--- a/src/Avalonia.Controls/Window.cs
+++ b/src/Avalonia.Controls/Window.cs
@@ -519,7 +519,7 @@ namespace Avalonia.Controls
}
}
- LayoutManager.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass();
using (BeginAutoSizing())
{
@@ -592,7 +592,7 @@ namespace Avalonia.Controls
}
}
- LayoutManager.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass();
var result = new TaskCompletionSource();
diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs
index afc01db506..eb6e7319f5 100644
--- a/src/Avalonia.Controls/WindowBase.cs
+++ b/src/Avalonia.Controls/WindowBase.cs
@@ -162,7 +162,7 @@ namespace Avalonia.Controls
if (!_hasExecutedInitialLayoutPass)
{
- LayoutManager.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass();
_hasExecutedInitialLayoutPass = true;
}
PlatformImpl?.Show();
diff --git a/src/Avalonia.Layout/ILayoutManager.cs b/src/Avalonia.Layout/ILayoutManager.cs
index 6e63d3edbb..d996b301f8 100644
--- a/src/Avalonia.Layout/ILayoutManager.cs
+++ b/src/Avalonia.Layout/ILayoutManager.cs
@@ -7,7 +7,7 @@ namespace Avalonia.Layout
///
/// Manages measuring and arranging of controls.
///
- public interface ILayoutManager
+ public interface ILayoutManager : IDisposable
{
///
/// Raised when the layout manager completes a layout pass.
@@ -35,6 +35,15 @@ namespace Avalonia.Layout
///
void ExecuteLayoutPass();
+ ///
+ /// Executes the initial layout pass on a layout root.
+ ///
+ ///
+ /// You should not usually need to call this method explictly, the layout root will call
+ /// it to carry out the initial layout of the control.
+ ///
+ void ExecuteInitialLayoutPass();
+
///
/// Executes the initial layout pass on a layout root.
///
@@ -43,6 +52,7 @@ namespace Avalonia.Layout
/// You should not usually need to call this method explictly, the layout root will call
/// it to carry out the initial layout of the control.
///
+ [Obsolete("Call ExecuteInitialLayoutPass without parameter")]
void ExecuteInitialLayoutPass(ILayoutRoot root);
}
}
diff --git a/src/Avalonia.Layout/LayoutManager.cs b/src/Avalonia.Layout/LayoutManager.cs
index aefb319fd0..c923aa62e9 100644
--- a/src/Avalonia.Layout/LayoutManager.cs
+++ b/src/Avalonia.Layout/LayoutManager.cs
@@ -10,16 +10,19 @@ namespace Avalonia.Layout
///
/// Manages measuring and arranging of controls.
///
- public class LayoutManager : ILayoutManager
+ public class LayoutManager : ILayoutManager, IDisposable
{
+ private readonly ILayoutRoot _owner;
private readonly LayoutQueue _toMeasure = new LayoutQueue(v => !v.IsMeasureValid);
private readonly LayoutQueue _toArrange = new LayoutQueue(v => !v.IsArrangeValid);
private readonly Action _executeLayoutPass;
+ private bool _disposed;
private bool _queued;
private bool _running;
- public LayoutManager()
+ public LayoutManager(ILayoutRoot owner)
{
+ _owner = owner ?? throw new ArgumentNullException(nameof(owner));
_executeLayoutPass = ExecuteLayoutPass;
}
@@ -31,6 +34,11 @@ namespace Avalonia.Layout
control = control ?? throw new ArgumentNullException(nameof(control));
Dispatcher.UIThread.VerifyAccess();
+ if (_disposed)
+ {
+ return;
+ }
+
if (!control.IsAttachedToVisualTree)
{
#if DEBUG
@@ -41,6 +49,11 @@ namespace Avalonia.Layout
#endif
}
+ if (control.VisualRoot != _owner)
+ {
+ throw new ArgumentException("Attempt to call InvalidateMeasure on wrong LayoutManager.");
+ }
+
_toMeasure.Enqueue(control);
_toArrange.Enqueue(control);
QueueLayoutPass();
@@ -52,6 +65,11 @@ namespace Avalonia.Layout
control = control ?? throw new ArgumentNullException(nameof(control));
Dispatcher.UIThread.VerifyAccess();
+ if (_disposed)
+ {
+ return;
+ }
+
if (!control.IsAttachedToVisualTree)
{
#if DEBUG
@@ -62,6 +80,11 @@ namespace Avalonia.Layout
#endif
}
+ if (control.VisualRoot != _owner)
+ {
+ throw new ArgumentException("Attempt to call InvalidateArrange on wrong LayoutManager.");
+ }
+
_toArrange.Enqueue(control);
QueueLayoutPass();
}
@@ -73,6 +96,11 @@ namespace Avalonia.Layout
Dispatcher.UIThread.VerifyAccess();
+ if (_disposed)
+ {
+ return;
+ }
+
if (!_running)
{
_running = true;
@@ -131,13 +159,18 @@ namespace Avalonia.Layout
}
///
- public virtual void ExecuteInitialLayoutPass(ILayoutRoot root)
+ public virtual void ExecuteInitialLayoutPass()
{
+ if (_disposed)
+ {
+ return;
+ }
+
try
{
_running = true;
- Measure(root);
- Arrange(root);
+ Measure(_owner);
+ Arrange(_owner);
}
finally
{
@@ -151,6 +184,24 @@ namespace Avalonia.Layout
ExecuteLayoutPass();
}
+ [Obsolete("Call ExecuteInitialLayoutPass without parameter")]
+ public void ExecuteInitialLayoutPass(ILayoutRoot root)
+ {
+ if (root != _owner)
+ {
+ throw new ArgumentException("ExecuteInitialLayoutPass called with incorrect root.");
+ }
+
+ ExecuteInitialLayoutPass();
+ }
+
+ public void Dispose()
+ {
+ _disposed = true;
+ _toMeasure.Dispose();
+ _toArrange.Dispose();
+ }
+
private void ExecuteMeasurePass()
{
while (_toMeasure.Count > 0)
diff --git a/src/Avalonia.Layout/LayoutQueue.cs b/src/Avalonia.Layout/LayoutQueue.cs
index e261a1b48e..1a9eb6b785 100644
--- a/src/Avalonia.Layout/LayoutQueue.cs
+++ b/src/Avalonia.Layout/LayoutQueue.cs
@@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace Avalonia.Layout
{
- internal class LayoutQueue : IReadOnlyCollection
+ internal class LayoutQueue : IReadOnlyCollection, IDisposable
{
private struct Info
{
@@ -84,5 +84,12 @@ namespace Avalonia.Layout
_notFinalizedBuffer.Clear();
}
+
+ public void Dispose()
+ {
+ _inner.Clear();
+ _loopQueueInfo.Clear();
+ _notFinalizedBuffer.Clear();
+ }
}
}
diff --git a/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs b/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs
index de40c247e6..7170f6d7d4 100644
--- a/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs
+++ b/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs
@@ -24,7 +24,7 @@ namespace Avalonia.Benchmarks.Layout
Renderer = new NullRenderer()
};
- _root.LayoutManager.ExecuteInitialLayoutPass(_root);
+ _root.LayoutManager.ExecuteInitialLayoutPass();
}
[Benchmark]
diff --git a/tests/Avalonia.Benchmarks/Layout/Measure.cs b/tests/Avalonia.Benchmarks/Layout/Measure.cs
index d03d17b4d3..fce2cddec9 100644
--- a/tests/Avalonia.Benchmarks/Layout/Measure.cs
+++ b/tests/Avalonia.Benchmarks/Layout/Measure.cs
@@ -25,7 +25,7 @@ namespace Avalonia.Benchmarks.Layout
_controls.Add(panel);
_controls = ControlHierarchyCreator.CreateChildren(_controls, panel, 3, 5, 5);
- _root.LayoutManager.ExecuteInitialLayoutPass(_root);
+ _root.LayoutManager.ExecuteInitialLayoutPass();
}
[Benchmark, MethodImpl(MethodImplOptions.NoInlining)]
diff --git a/tests/Avalonia.Benchmarks/Traversal/VisualTreeTraversal.cs b/tests/Avalonia.Benchmarks/Traversal/VisualTreeTraversal.cs
index fc2380d670..c6da3a941f 100644
--- a/tests/Avalonia.Benchmarks/Traversal/VisualTreeTraversal.cs
+++ b/tests/Avalonia.Benchmarks/Traversal/VisualTreeTraversal.cs
@@ -26,7 +26,7 @@ namespace Avalonia.Benchmarks.Traversal
_shuffledControls = _controls.OrderBy(r => random.Next()).ToList();
- _root.LayoutManager.ExecuteInitialLayoutPass(_root);
+ _root.LayoutManager.ExecuteInitialLayoutPass();
}
[Benchmark]
diff --git a/tests/Avalonia.Controls.UnitTests/GridTests.cs b/tests/Avalonia.Controls.UnitTests/GridTests.cs
index b3882c534b..4ffa526b85 100644
--- a/tests/Avalonia.Controls.UnitTests/GridTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/GridTests.cs
@@ -1194,7 +1194,7 @@ namespace Avalonia.Controls.UnitTests
Height = 50,
};
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
PrintColumnDefinitions(grids[0]);
Assert.Equal(5, grids[0].ColumnDefinitions[0].ActualWidth);
diff --git a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
index a7679ba388..c4346e571b 100644
--- a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
@@ -329,7 +329,7 @@ namespace Avalonia.Controls.UnitTests
return tb;
}, true);
- lm.ExecuteInitialLayoutPass(wnd);
+ lm.ExecuteInitialLayoutPass();
target.Items = items;
diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs
index 9caae89cfe..d529cc4f75 100644
--- a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs
+++ b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs
@@ -232,7 +232,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
var scroll = (TestScroller)target.Parent;
scroll.Width = scroll.Height = 100;
- scroll.LayoutManager.ExecuteInitialLayoutPass(scroll);
+ scroll.LayoutManager.ExecuteInitialLayoutPass();
// Ensure than an intermediate measure pass doesn't add more controls than it
// should. This can happen if target gets measured with Size.Infinity which
@@ -324,6 +324,11 @@ namespace Avalonia.Controls.UnitTests.Presenters
private class TestScroller : ScrollContentPresenter, IRenderRoot, ILayoutRoot
{
+ public TestScroller()
+ {
+ LayoutManager = new LayoutManager(this);
+ }
+
public IRenderer Renderer { get; }
public Size ClientSize { get; }
public double RenderScaling => 1;
@@ -332,7 +337,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
public double LayoutScaling => 1;
- public ILayoutManager LayoutManager { get; } = new LayoutManager();
+ public ILayoutManager LayoutManager { get; }
public IRenderTarget CreateRenderTarget() => throw new NotImplementedException();
public void Invalidate(Rect rect) => throw new NotImplementedException();
diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
index 5a2cb60a56..a467c6dd03 100644
--- a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
+++ b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
@@ -723,7 +723,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
var scroller = (TestScroller)target.Parent;
scroller.Width = scroller.Height = 100;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
var last = (target.Items as IList)[10];
@@ -740,7 +740,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
var scroller = (TestScroller)target.Parent;
scroller.Width = scroller.Height = 100;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
var last = (target.Items as IList)[10];
@@ -838,7 +838,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
var scroller = (TestScroller)target.Parent;
scroller.Width = scroller.Height = 100;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
var from = target.Panel.Children[5];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@@ -855,7 +855,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
var scroller = (TestScroller)target.Parent;
scroller.Width = scroller.Height = 100;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
var from = target.Panel.Children[9];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@@ -874,7 +874,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
scroller.Width = 100;
scroller.Height = 95;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
var from = target.Panel.Children[8];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@@ -893,7 +893,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
scroller.Width = 100;
scroller.Height = 95;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
((ILogicalScrollable)target).Offset = new Vector(0, 11);
var from = target.Panel.Children[1];
@@ -946,7 +946,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
var scroller = (TestScroller)target.Parent;
scroller.Width = scroller.Height = 100;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
var from = target.Panel.Children[5];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@@ -963,7 +963,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
var scroller = (TestScroller)target.Parent;
scroller.Width = scroller.Height = 100;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
var from = target.Panel.Children[9];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@@ -982,7 +982,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
scroller.Width = 95;
scroller.Height = 100;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
var from = target.Panel.Children[8];
var result = ((ILogicalScrollable)target).GetControlInDirection(
@@ -1001,7 +1001,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
scroller.Width = 95;
scroller.Height = 100;
- scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+ scroller.LayoutManager.ExecuteInitialLayoutPass();
((ILogicalScrollable)target).Offset = new Vector(11, 0);
var from = target.Panel.Children[1];
@@ -1062,6 +1062,11 @@ namespace Avalonia.Controls.UnitTests.Presenters
private class TestScroller : ScrollContentPresenter, IRenderRoot, ILayoutRoot, ILogicalRoot
{
+ public TestScroller()
+ {
+ LayoutManager = new LayoutManager(this);
+ }
+
public IRenderer Renderer { get; }
public Size ClientSize { get; }
public double RenderScaling => 1;
@@ -1070,7 +1075,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
public double LayoutScaling => 1;
- public ILayoutManager LayoutManager { get; } = new LayoutManager();
+ public ILayoutManager LayoutManager { get; }
public IRenderTarget CreateRenderTarget() => throw new NotImplementedException();
public void Invalidate(Rect rect) => throw new NotImplementedException();
diff --git a/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs b/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs
index deca3cfb75..ab21c5d330 100644
--- a/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs
@@ -158,7 +158,7 @@ namespace Avalonia.Controls.UnitTests
target.SetValue(ScrollViewer.ViewportProperty, new Size(50, 50));
target.Offset = new Vector(10, 10);
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
target.ScrollChanged += (s, e) =>
{
@@ -188,7 +188,7 @@ namespace Avalonia.Controls.UnitTests
target.SetValue(ScrollViewer.ViewportProperty, new Size(50, 50));
target.Offset = new Vector(10, 10);
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
target.ScrollChanged += (s, e) =>
{
@@ -218,7 +218,7 @@ namespace Avalonia.Controls.UnitTests
target.SetValue(ScrollViewer.ViewportProperty, new Size(50, 50));
target.Offset = new Vector(10, 10);
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
target.ScrollChanged += (s, e) =>
{
diff --git a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
index 6b107b0187..e49e273bec 100644
--- a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
@@ -106,7 +106,7 @@ namespace Avalonia.Controls.UnitTests
}
};
- target.LayoutManager.ExecuteInitialLayoutPass(target);
+ target.LayoutManager.ExecuteInitialLayoutPass();
Assert.Equal(new Rect(0, 0, 321, 432), target.Bounds);
}
@@ -267,6 +267,23 @@ namespace Avalonia.Controls.UnitTests
}
}
+ [Fact]
+ public void Close_Should_Dispose_LayoutManager()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var impl = new Mock();
+ impl.SetupAllProperties();
+
+ var layoutManager = new Mock();
+ var target = new TestTopLevel(impl.Object, layoutManager.Object);
+
+ impl.Object.Closed();
+
+ layoutManager.Verify(x => x.Dispose());
+ }
+ }
+
[Fact]
public void Reacts_To_Changes_In_Global_Styles()
{
@@ -282,7 +299,7 @@ namespace Avalonia.Controls.UnitTests
Content = child,
};
- target.LayoutManager.ExecuteInitialLayoutPass(target);
+ target.LayoutManager.ExecuteInitialLayoutPass();
Assert.Equal(new Thickness(0), child.BorderThickness);
@@ -295,7 +312,7 @@ namespace Avalonia.Controls.UnitTests
};
Application.Current.Styles.Add(style);
- target.LayoutManager.ExecuteInitialLayoutPass(target);
+ target.LayoutManager.ExecuteInitialLayoutPass();
Assert.Equal(new Thickness(2), child.BorderThickness);
@@ -323,7 +340,7 @@ namespace Avalonia.Controls.UnitTests
public TestTopLevel(ITopLevelImpl impl, ILayoutManager layoutManager = null)
: base(impl)
{
- _layoutManager = layoutManager ?? new LayoutManager();
+ _layoutManager = layoutManager ?? new LayoutManager(this);
}
protected override ILayoutManager CreateLayoutManager() => _layoutManager;
diff --git a/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs b/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs
index 332e8a751d..e429adce85 100644
--- a/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs
+++ b/tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs
@@ -13,7 +13,7 @@ namespace Avalonia.Layout.UnitTests
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
control.Measured = control.Arranged = false;
control.InvalidateMeasure();
@@ -23,13 +23,29 @@ namespace Avalonia.Layout.UnitTests
Assert.True(control.Arranged);
}
+ [Fact]
+ public void Doesnt_Measure_And_Arrange_InvalidateMeasured_Control_When_TopLevel_Is_Not_Visible()
+ {
+ var control = new LayoutTestControl();
+ var root = new LayoutTestRoot { Child = control, IsVisible = false };
+
+ root.LayoutManager.ExecuteInitialLayoutPass();
+ control.Measured = control.Arranged = false;
+
+ control.InvalidateMeasure();
+ root.LayoutManager.ExecuteLayoutPass();
+
+ Assert.False(control.Measured);
+ Assert.False(control.Arranged);
+ }
+
[Fact]
public void Arranges_InvalidateArranged_Control()
{
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
control.Measured = control.Arranged = false;
control.InvalidateArrange();
@@ -45,7 +61,7 @@ namespace Avalonia.Layout.UnitTests
var control = new LayoutTestControl();
var root = new LayoutTestRoot();
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
root.Child = control;
root.Measured = root.Arranged = false;
@@ -80,7 +96,7 @@ namespace Avalonia.Layout.UnitTests
root.DoMeasureOverride = MeasureOverride;
control1.DoMeasureOverride = MeasureOverride;
control2.DoMeasureOverride = MeasureOverride;
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
control2.InvalidateMeasure();
control1.InvalidateMeasure();
@@ -115,7 +131,7 @@ namespace Avalonia.Layout.UnitTests
root.DoMeasureOverride = MeasureOverride;
control1.DoMeasureOverride = MeasureOverride;
control2.DoMeasureOverride = MeasureOverride;
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
control2.InvalidateMeasure();
root.InvalidateMeasure();
@@ -132,7 +148,7 @@ namespace Avalonia.Layout.UnitTests
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
root.Measured = root.Arranged = false;
control.Measured = control.Arranged = false;
@@ -151,7 +167,7 @@ namespace Avalonia.Layout.UnitTests
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
control.Measured = control.Arranged = false;
control.InvalidateMeasure();
@@ -177,7 +193,7 @@ namespace Avalonia.Layout.UnitTests
return new Size(100, 100);
};
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
Assert.Equal(Size.Infinity, availableSize);
}
@@ -199,7 +215,7 @@ namespace Avalonia.Layout.UnitTests
return s;
};
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
Assert.Equal(new Size(100, 100), arrangeSize);
root.Width = 120;
@@ -225,7 +241,7 @@ namespace Avalonia.Layout.UnitTests
}
};
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
Assert.Equal(new Size(0, 0), root.DesiredSize);
border.Width = 100;
@@ -241,7 +257,7 @@ namespace Avalonia.Layout.UnitTests
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
control.Measured = false;
int cnt = 0;
@@ -272,7 +288,7 @@ namespace Avalonia.Layout.UnitTests
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
control.Arranged = false;
int cnt = 0;
@@ -313,7 +329,7 @@ namespace Avalonia.Layout.UnitTests
panel.Children.AddRange(nonArrageableTargets);
panel.Children.AddRange(targets);
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
foreach (var c in panel.Children.OfType())
{
@@ -347,7 +363,7 @@ namespace Avalonia.Layout.UnitTests
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
control.Measured = false;
control.DoMeasureOverride = (l, s) =>
@@ -380,7 +396,7 @@ namespace Avalonia.Layout.UnitTests
var root = new LayoutTestRoot { Child = control };
var count = 0;
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
control.Measured = false;
control.DoMeasureOverride = (l, s) =>
@@ -399,7 +415,7 @@ namespace Avalonia.Layout.UnitTests
root.InvalidateMeasure();
control.InvalidateMeasure();
- root.LayoutManager.ExecuteInitialLayoutPass(root);
+ root.LayoutManager.ExecuteInitialLayoutPass();
Assert.Equal(new Size(200, 200), control.Bounds.Size);
Assert.Equal(new Size(200, 200), control.DesiredSize);
diff --git a/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs b/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs
index a21c8d589d..44a5af94b9 100644
--- a/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs
+++ b/tests/Avalonia.Layout.UnitTests/LayoutableTests.cs
@@ -208,14 +208,12 @@ namespace Avalonia.Layout.UnitTests
{
Border border1;
Border border2;
- var layoutManager = new LayoutManager();
var root = new TestRoot
{
Child = border1 = new Border
{
Child = border2 = new Border(),
},
- LayoutManager = layoutManager,
};
var raised = 0;
@@ -233,7 +231,7 @@ namespace Avalonia.Layout.UnitTests
root.Measure(new Size(100, 100));
root.Arrange(new Rect(0, 0, 100, 100));
- layoutManager.ExecuteLayoutPass();
+ root.LayoutManager.ExecuteLayoutPass();
Assert.Equal(3, raised);
Assert.Equal(new Rect(0, 0, 100, 100), border1.Bounds);
diff --git a/tests/Avalonia.LeakTests/ControlTests.cs b/tests/Avalonia.LeakTests/ControlTests.cs
index e3a8f9455f..00ef503b8d 100644
--- a/tests/Avalonia.LeakTests/ControlTests.cs
+++ b/tests/Avalonia.LeakTests/ControlTests.cs
@@ -44,7 +44,7 @@ namespace Avalonia.LeakTests
window.Show();
// Do a layout and make sure that Canvas gets added to visual tree.
- window.LayoutManager.ExecuteInitialLayoutPass(window);
+ window.LayoutManager.ExecuteInitialLayoutPass();
Assert.IsType