|
|
@@ -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
|
|
|
{
|
|
|
@@ -107,6 +109,20 @@ namespace Avalonia.Controls.UnitTests.Presenters
|
|
|
Assert.Same(target, content.Parent);
|
|
|
}
|
|
|
|
|
|
+ [Fact]
|
|
|
+ public void Should_Add_Child_To_Own_LogicalChildren_Outside_Template()
|
|
|
+ {
|
|
|
+ var content = new Border();
|
|
|
+ var target = new ContentPresenter { Content = content };
|
|
|
+
|
|
|
+ target.UpdateChild();
|
|
|
+
|
|
|
+ var logicalChildren = target.GetLogicalChildren();
|
|
|
+
|
|
|
+ Assert.Equal(1, logicalChildren.Count());
|
|
|
+ Assert.Equal(content, logicalChildren.First());
|
|
|
+ }
|
|
|
+
|
|
|
[Fact]
|
|
|
public void Adding_To_Logical_Tree_Should_Reevaluate_DataTemplates()
|
|
|
{
|
|
|
@@ -178,9 +194,162 @@ namespace Avalonia.Controls.UnitTests.Presenters
|
|
|
Assert.Same(control, target.Child);
|
|
|
}
|
|
|
|
|
|
+ [Fact]
|
|
|
+ public void Should_Raise_DetachedFromLogicalTree_On_Content_Changed_OutsideTemplate()
|
|
|
+ {
|
|
|
+ var target = new ContentPresenter
|
|
|
+ {
|
|
|
+ ContentTemplate =
|
|
|
+ new FuncDataTemplate<string>(t => new ContentControl() { Content = t }, false)
|
|
|
+ };
|
|
|
+
|
|
|
+ var parentMock = new Mock<Control>();
|
|
|
+ parentMock.As<IContentPresenterHost>();
|
|
|
+ parentMock.As<IStyleRoot>();
|
|
|
+
|
|
|
+ (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_OutsideTemplate()
|
|
|
+ {
|
|
|
+ var contentControl = new ContentControl
|
|
|
+ {
|
|
|
+ Template = new FuncControlTemplate<ContentControl>(c => new ContentPresenter()
|
|
|
+ {
|
|
|
+ Name = "PART_ContentPresenter",
|
|
|
+ [~ContentPresenter.ContentProperty] = c[~ContentControl.ContentProperty],
|
|
|
+ [~ContentPresenter.ContentTemplateProperty] = c[~ContentControl.ContentTemplateProperty]
|
|
|
+ }),
|
|
|
+ ContentTemplate =
|
|
|
+ new FuncDataTemplate<string>(t => new ContentControl() { Content = t }, false)
|
|
|
+ };
|
|
|
+
|
|
|
+ var parentMock = new Mock<Control>();
|
|
|
+ parentMock.As<IStyleRoot>();
|
|
|
+ parentMock.As<ILogical>().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);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public void Should_Raise_DetachedFromLogicalTree_On_Detached_OutsideTemplate()
|
|
|
+ {
|
|
|
+ var target = new ContentPresenter
|
|
|
+ {
|
|
|
+ ContentTemplate =
|
|
|
+ new FuncDataTemplate<string>(t => new ContentControl() { Content = t }, false)
|
|
|
+ };
|
|
|
+
|
|
|
+ var parentMock = new Mock<Control>();
|
|
|
+ parentMock.As<IContentPresenterHost>();
|
|
|
+ parentMock.As<IStyleRoot>();
|
|
|
+
|
|
|
+ (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 as ISetLogicalParent).SetParent(null);
|
|
|
+
|
|
|
+ Assert.False((foo as IControl).IsAttachedToLogicalTree);
|
|
|
+ Assert.True(foodetached);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public void Should_Remove_Old_Child_From_LogicalChildren_On_ContentChanged_OutsideTemplate()
|
|
|
+ {
|
|
|
+ var target = new ContentPresenter
|
|
|
+ {
|
|
|
+ ContentTemplate =
|
|
|
+ new FuncDataTemplate<string>(t => new ContentControl() { Content = t }, false)
|
|
|
+ };
|
|
|
+
|
|
|
+ target.Content = "foo";
|
|
|
+
|
|
|
+ target.UpdateChild();
|
|
|
+
|
|
|
+ var foo = target.Child as ContentControl;
|
|
|
+
|
|
|
+ Assert.NotNull(foo);
|
|
|
+
|
|
|
+ var logicalChildren = target.GetLogicalChildren();
|
|
|
+
|
|
|
+ Assert.Equal(1, logicalChildren.Count());
|
|
|
+
|
|
|
+ target.Content = "bar";
|
|
|
+ target.UpdateChild();
|
|
|
+
|
|
|
+ Assert.Equal(null, foo.Parent);
|
|
|
+
|
|
|
+ logicalChildren = target.GetLogicalChildren();
|
|
|
+
|
|
|
+ Assert.Equal(1, logicalChildren.Count());
|
|
|
+ Assert.NotEqual(foo, logicalChildren.First());
|
|
|
+ }
|
|
|
+
|
|
|
private class TestContentControl : ContentControl
|
|
|
{
|
|
|
public IControl Child { get; set; }
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}
|