diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests.cs index 5c26ba5a5e..eeda582d35 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests.cs @@ -1,15 +1,17 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. -using System.Linq; -using Moq; using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; +using Avalonia.LogicalTree; +using Avalonia.Styling; using Avalonia.UnitTests; using Avalonia.VisualTree; -using Xunit; +using Moq; using System; +using System.Linq; +using Xunit; namespace Avalonia.Controls.UnitTests.Presenters { @@ -178,9 +180,98 @@ namespace Avalonia.Controls.UnitTests.Presenters Assert.Same(control, target.Child); } + [Fact] + public void Should_Raise_DetachedFromLogicalTree_On_Content_Changed() + { + var target = new ContentPresenter + { + ContentTemplate = + new FuncDataTemplate(t => new ContentControl() { Content = t }, false) + }; + + var parentMock = new Mock(); + parentMock.As(); + parentMock.As(); + + // target.SetValue(ContentPresenter.TemplatedParentProperty, parentMock.Object); + + (target as ISetLogicalParent).SetParent(parentMock.Object); + + target.Content = "foo"; + + target.UpdateChild(); + + var foo = target.Child as ContentControl; + + bool foodetached = false; + + Assert.NotNull(foo); + Assert.Equal("foo", foo.Content); + + foo.DetachedFromLogicalTree += delegate { foodetached = true; }; + + target.Content = "bar"; + target.UpdateChild(); + + var bar = target.Child as ContentControl; + + Assert.NotNull(bar); + Assert.True(bar != foo); + Assert.False((foo as IControl).IsAttachedToLogicalTree); + Assert.True(foodetached); + } + + [Fact] + public void Should_Raise_DetachedFromLogicalTree_In_ContentControl_On_Content_Changed() + { + var contentControl = new ContentControl + { + Template = new FuncControlTemplate(c => new ContentPresenter() + { + Name = "PART_ContentPresenter", + [~ContentPresenter.ContentProperty] = c[~ContentControl.ContentProperty], + [~ContentPresenter.ContentTemplateProperty] = c[~ContentControl.ContentTemplateProperty] + }), + ContentTemplate = + new FuncDataTemplate(t => new ContentControl() { Content = t }, false) + }; + + var parentMock = new Mock(); + parentMock.As(); + parentMock.As().SetupGet(l => l.IsAttachedToLogicalTree).Returns(true); + + (contentControl as ISetLogicalParent).SetParent(parentMock.Object); + + contentControl.ApplyTemplate(); + var target = contentControl.Presenter as ContentPresenter; + + contentControl.Content = "foo"; + + target.UpdateChild(); + + var tbfoo = target.Child as ContentControl; + + bool foodetached = false; + + Assert.NotNull(tbfoo); + Assert.Equal("foo", tbfoo.Content); + + tbfoo.DetachedFromLogicalTree += delegate { foodetached = true; }; + + contentControl.Content = "bar"; + target.UpdateChild(); + + var tbbar = target.Child as ContentControl; + + Assert.NotNull(tbbar); + Assert.True(tbbar != tbfoo); + Assert.False((tbfoo as IControl).IsAttachedToLogicalTree); + Assert.True(foodetached); + } + private class TestContentControl : ContentControl { public IControl Child { get; set; } } } -} +} \ No newline at end of file