Browse Source

Merge branch 'master' into fixes/1004-remove-devtools-reactiveui-depenency

Steven Kirk 8 years ago
parent
commit
d506eb10f8
2 changed files with 90 additions and 2 deletions
  1. 13 2
      src/Avalonia.Controls/Window.cs
  2. 77 0
      tests/Avalonia.Controls.UnitTests/WindowTests.cs

+ 13 - 2
src/Avalonia.Controls/Window.cs

@@ -47,12 +47,12 @@ namespace Avalonia.Controls
     /// </summary>
     public class Window : WindowBase, IStyleable, IFocusScope, ILayoutRoot, INameScope
     {
-        private static IList<Window> s_windows = new List<Window>();
+        private static List<Window> s_windows = new List<Window>();
 
         /// <summary>
         /// Retrieves an enumeration of all Windows in the currently running application.
         /// </summary>
-        public static IList<Window> OpenWindows => s_windows;
+        public static IReadOnlyList<Window> OpenWindows => s_windows;
 
         /// <summary>
         /// Defines the <see cref="SizeToContent"/> property.
@@ -238,6 +238,11 @@ namespace Avalonia.Controls
         /// </summary>
         public override void Show()
         {
+            if (IsVisible)
+            {
+                return;
+            }
+
             s_windows.Add(this);
 
             EnsureInitialized();
@@ -272,6 +277,11 @@ namespace Avalonia.Controls
         /// </returns>
         public Task<TResult> ShowDialog<TResult>()
         {
+            if (IsVisible)
+            {
+                throw new InvalidOperationException("The window is already being shown.");
+            }
+
             s_windows.Add(this);
 
             EnsureInitialized();
@@ -360,6 +370,7 @@ namespace Avalonia.Controls
         protected override void HandleClosed()
         {
             IsVisible = false;
+            s_windows.Remove(this);
             base.HandleClosed();
         }
 

+ 77 - 0
tests/Avalonia.Controls.UnitTests/WindowTests.cs

@@ -4,6 +4,7 @@
 // </copyright>
 // -----------------------------------------------------------------------
 
+using System.Collections.Generic;
 using Avalonia.Platform;
 using Avalonia.UnitTests;
 using Moq;
@@ -114,5 +115,81 @@ namespace Avalonia.Controls.UnitTests
                 Assert.False(window.IsVisible);
             }
         }
+
+        [Fact]
+        public void Show_Should_Add_Window_To_OpenWindows()
+        {
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
+            {
+                ClearOpenWindows();
+                var window = new Window();
+
+                window.Show();
+
+                Assert.Equal(new[] { window }, Window.OpenWindows);
+            }
+        }
+
+        [Fact]
+        public void Window_Should_Be_Added_To_OpenWindows_Only_Once()
+        {
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
+            {
+                ClearOpenWindows();
+                var window = new Window();
+
+                window.Show();
+                window.Show();
+                window.IsVisible = true;
+
+                Assert.Equal(new[] { window }, Window.OpenWindows);
+
+                window.Close();
+            }
+        }
+
+        [Fact]
+        public void Close_Should_Remove_Window_From_OpenWindows()
+        {
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
+            {
+                ClearOpenWindows();
+                var window = new Window();
+
+                window.Show();
+                window.Close();
+
+                Assert.Empty(Window.OpenWindows);
+            }
+        }
+
+        [Fact]
+        public void Impl_Closing_Should_Remove_Window_From_OpenWindows()
+        {
+            var windowImpl = new Mock<IWindowImpl>();
+            windowImpl.SetupProperty(x => x.Closed);
+            windowImpl.Setup(x => x.Scaling).Returns(1);
+
+            var services = TestServices.StyledWindow.With(
+                windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
+
+            using (UnitTestApplication.Start(services))
+            {
+                ClearOpenWindows();
+                var window = new Window();
+
+                window.Show();
+                windowImpl.Object.Closed();
+
+                Assert.Empty(Window.OpenWindows);
+            }
+        }
+
+        private void ClearOpenWindows()
+        {
+            // HACK: We really need a decent way to have "statics" that can be scoped to
+            // AvaloniaLocator scopes.
+            ((IList<Window>)Window.OpenWindows).Clear();
+        }
     }
 }