From 663e760fdaf19bca8cec6f861db1cccc774ab632 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 13 Oct 2015 12:35:01 +0200 Subject: [PATCH] Throw exception if TopLevel added as child. Closes #262. --- src/Perspex.Controls/TopLevel.cs | 9 ++++ .../TopLevelTests.cs | 42 ++++++++++++++----- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/Perspex.Controls/TopLevel.cs b/src/Perspex.Controls/TopLevel.cs index 25572b588d..21247721bd 100644 --- a/src/Perspex.Controls/TopLevel.cs +++ b/src/Perspex.Controls/TopLevel.cs @@ -286,6 +286,15 @@ namespace Perspex.Controls PlatformImpl.Invalidate(new Rect(clientSize)); } + /// + protected override void OnAttachedToVisualTree(IRenderRoot root) + { + base.OnAttachedToVisualTree(root); + + throw new InvalidOperationException( + $"Control '{GetType().Name}' is a top level control and cannot be added as a child."); + } + /// /// Tries to get a service from an , throwing an /// exception if not found. diff --git a/tests/Perspex.Controls.UnitTests/TopLevelTests.cs b/tests/Perspex.Controls.UnitTests/TopLevelTests.cs index c4d8f324df..aa489b44bc 100644 --- a/tests/Perspex.Controls.UnitTests/TopLevelTests.cs +++ b/tests/Perspex.Controls.UnitTests/TopLevelTests.cs @@ -1,6 +1,7 @@ // Copyright (c) The Perspex Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; using System.Reactive; using System.Reactive.Subjects; using Moq; @@ -98,11 +99,7 @@ namespace Perspex.Controls.UnitTests var target = new TestTopLevel(impl.Object) { - Template = new ControlTemplate(x => - new ContentPresenter - { - [~ContentPresenter.ContentProperty] = x[~ContentControl.ContentProperty], - }), + Template = CreateTemplate(), Content = new TextBlock { Width = 321, @@ -128,11 +125,7 @@ namespace Perspex.Controls.UnitTests var target = new TestTopLevel(impl.Object) { - Template = new ControlTemplate(x => - new ContentPresenter - { - [~ContentPresenter.ContentProperty] = x[~ContentControl.ContentProperty], - }), + Template = CreateTemplate(), Content = new TextBlock { Width = 321, @@ -304,6 +297,34 @@ namespace Perspex.Controls.UnitTests } } + [Fact] + public void Adding_Top_Level_As_Child_Should_Throw_Exception() + { + using (PerspexLocator.EnterScope()) + { + RegisterServices(); + + var impl = new Mock(); + impl.SetupAllProperties(); + var target = new TestTopLevel(impl.Object); + var child = new TestTopLevel(impl.Object); + + target.Template = CreateTemplate(); + target.Content = child; + + Assert.Throws(() => target.ApplyTemplate()); + } + } + + private ControlTemplate CreateTemplate() + { + return new ControlTemplate(x => + new ContentPresenter + { + [!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty], + }); + } + private void RegisterServices() { var fixture = new Fixture().Customize(new AutoMoqCustomization()); @@ -319,7 +340,6 @@ namespace Perspex.Controls.UnitTests globalStyles.Setup(x => x.Styles).Returns(theme); - PerspexLocator.CurrentMutable .Bind().ToConstant(new Mock().Object) .Bind().ToConstant(new Mock().Object)