Browse Source

Don't reomve old content from logicaltree

pull/9803/head
daniel 3 years ago
parent
commit
4780567438
  1. 11
      src/Avalonia.Controls/ContentControl.cs
  2. 7
      src/Avalonia.Controls/TransitioningContentControl.cs
  3. 63
      tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs

11
src/Avalonia.Controls/ContentControl.cs

@ -116,14 +116,19 @@ namespace Avalonia.Controls
return false;
}
private void ContentChanged(AvaloniaPropertyChangedEventArgs e)
protected virtual void ContentChanged(AvaloniaPropertyChangedEventArgs e)
{
if (e.OldValue is ILogical oldChild)
UpdateLogicalTree(e.OldValue, e.NewValue);
}
protected void UpdateLogicalTree(object? toRemove, object? toAdd)
{
if (toRemove is ILogical oldChild)
{
LogicalChildren.Remove(oldChild);
}
if (e.NewValue is ILogical newChild)
if (toAdd is ILogical newChild)
{
LogicalChildren.Add(newChild);
}

7
src/Avalonia.Controls/TransitioningContentControl.cs

@ -71,6 +71,11 @@ public class TransitioningContentControl : ContentControl
}
}
protected override void ContentChanged(AvaloniaPropertyChangedEventArgs e)
{
// We do nothing becuse we should not remove old Content until the animation is over
}
/// <summary>
/// Updates the content with transitions.
/// </summary>
@ -89,6 +94,8 @@ public class TransitioningContentControl : ContentControl
if (PageTransition != null)
await PageTransition.Start(this, null, true, localToken);
UpdateLogicalTree(CurrentContent, content);
if (localToken.IsCancellationRequested)
{
return;

63
tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs

@ -0,0 +1,63 @@
using System;
using Avalonia.LogicalTree;
using Avalonia.UnitTests;
using Xunit;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Animation;
namespace Avalonia.Controls.UnitTests
{
public class TransitioningContentControlTests
{
[Fact]
public void Old_Content_Shuold_Be_Removed__From_Logical_Tree_After_Out_Animation()
{
var testTransition = new TestTransition();
var target = new TransitioningContentControl();
target.PageTransition = testTransition;
var root = new TestRoot() { Child = target };
var oldControl = new Control();
var newControl = new Control();
target.Content = oldControl;
Threading.Dispatcher.UIThread.RunJobs();
Assert.Equal(target, oldControl.GetLogicalParent());
Assert.Equal(null, newControl.GetLogicalParent());
testTransition.BeginTransition += isFrom =>
{
// Old out
if (isFrom)
{
Assert.Equal(target, oldControl.GetLogicalParent());
Assert.Equal(null, newControl.GetLogicalParent());
}
// New in
else
{
Assert.Equal(null, oldControl.GetLogicalParent());
Assert.Equal(target, newControl.GetLogicalParent());
}
};
target.Content = newControl;
Threading.Dispatcher.UIThread.RunJobs();
}
}
public class TestTransition : IPageTransition
{
public event Action<bool> BeginTransition;
public Task Start(Visual from, Visual to, bool forward, CancellationToken cancellationToken)
{
bool isFrom = from != null && to == null;
BeginTransition?.Invoke(isFrom);
return Task.CompletedTask;
}
}
}
Loading…
Cancel
Save