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)