diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs
index 5d34444eb8..c738a5ff3b 100644
--- a/src/Avalonia.Controls/TopLevel.cs
+++ b/src/Avalonia.Controls/TopLevel.cs
@@ -315,7 +315,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 .
diff --git a/src/Avalonia.Layout/ILayoutManager.cs b/src/Avalonia.Layout/ILayoutManager.cs
index 6e63d3edbb..688b6b83e5 100644
--- a/src/Avalonia.Layout/ILayoutManager.cs
+++ b/src/Avalonia.Layout/ILayoutManager.cs
@@ -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..a81f2b61b7 100644
--- a/src/Avalonia.Layout/LayoutManager.cs
+++ b/src/Avalonia.Layout/LayoutManager.cs
@@ -12,14 +12,16 @@ namespace Avalonia.Layout
///
public class LayoutManager : ILayoutManager
{
+ 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 _queued;
private bool _running;
- public LayoutManager()
+ public LayoutManager(ILayoutRoot owner)
{
+ _owner = owner ?? throw new ArgumentNullException(nameof(owner));
_executeLayoutPass = ExecuteLayoutPass;
}
@@ -73,6 +75,11 @@ namespace Avalonia.Layout
Dispatcher.UIThread.VerifyAccess();
+ if (!_owner.IsVisible)
+ {
+ return;
+ }
+
if (!_running)
{
_running = true;
@@ -131,13 +138,13 @@ namespace Avalonia.Layout
}
///
- public virtual void ExecuteInitialLayoutPass(ILayoutRoot root)
+ public virtual void ExecuteInitialLayoutPass()
{
try
{
_running = true;
- Measure(root);
- Arrange(root);
+ Measure(_owner);
+ Arrange(_owner);
}
finally
{
@@ -151,6 +158,17 @@ 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();
+ }
+
private void ExecuteMeasurePass()
{
while (_toMeasure.Count > 0)
@@ -228,7 +246,7 @@ namespace Avalonia.Layout
private void QueueLayoutPass()
{
- if (!_queued && !_running)
+ if (!_queued && !_running && _owner.IsVisible)
{
Dispatcher.UIThread.Post(_executeLayoutPass, DispatcherPriority.Layout);
_queued = true;
diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs
index 9caae89cfe..3320ced8a4 100644
--- a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs
+++ b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs
@@ -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..d3fa565f4c 100644
--- a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
+++ b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
@@ -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/TopLevelTests.cs b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
index 6b107b0187..e5ff8d04de 100644
--- a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
@@ -323,7 +323,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/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.UnitTests/TestRoot.cs b/tests/Avalonia.UnitTests/TestRoot.cs
index f291d386aa..b6f3a020e8 100644
--- a/tests/Avalonia.UnitTests/TestRoot.cs
+++ b/tests/Avalonia.UnitTests/TestRoot.cs
@@ -19,6 +19,8 @@ namespace Avalonia.UnitTests
public TestRoot()
{
Renderer = Mock.Of();
+ LayoutManager = new LayoutManager(this);
+ IsVisible = true;
}
public TestRoot(IControl child)
@@ -44,7 +46,7 @@ namespace Avalonia.UnitTests
public double LayoutScaling { get; set; } = 1;
- public ILayoutManager LayoutManager { get; set; } = new LayoutManager();
+ public ILayoutManager LayoutManager { get; set; }
public double RenderScaling => 1;
diff --git a/tests/Avalonia.UnitTests/TestTemplatedRoot.cs b/tests/Avalonia.UnitTests/TestTemplatedRoot.cs
index da4d92ce5e..38ab3c3c5d 100644
--- a/tests/Avalonia.UnitTests/TestTemplatedRoot.cs
+++ b/tests/Avalonia.UnitTests/TestTemplatedRoot.cs
@@ -16,6 +16,7 @@ namespace Avalonia.UnitTests
public TestTemplatedRoot()
{
+ LayoutManager = new LayoutManager(this);
Template = new FuncControlTemplate((x, scope) => new ContentPresenter
{
Name = "PART_ContentPresenter",
@@ -28,7 +29,7 @@ namespace Avalonia.UnitTests
public double LayoutScaling => 1;
- public ILayoutManager LayoutManager { get; set; } = new LayoutManager();
+ public ILayoutManager LayoutManager { get; set; }
public double RenderScaling => 1;