From a7ff93450e1fa527cda6aa26d2896be1432cb2bc Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 27 May 2017 14:05:44 +0200 Subject: [PATCH] Fixed problems with Windows.OpenWindows. - Showing a window was causing it to be added to the collection twice because `Show()` called `IsVisible = true` which called `Show()` - The window wasn't getting removed when the `PlatformImpl` signalled it was closed --- src/Avalonia.Controls/Window.cs | 11 +++ .../WindowTests.cs | 67 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 32eaf499f0..39f9a8d272 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -238,6 +238,11 @@ namespace Avalonia.Controls /// public override void Show() { + if (IsVisible) + { + return; + } + s_windows.Add(this); EnsureInitialized(); @@ -272,6 +277,11 @@ namespace Avalonia.Controls /// public Task ShowDialog() { + 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(); } diff --git a/tests/Avalonia.Controls.UnitTests/WindowTests.cs b/tests/Avalonia.Controls.UnitTests/WindowTests.cs index 96afecc966..d2b882310d 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowTests.cs +++ b/tests/Avalonia.Controls.UnitTests/WindowTests.cs @@ -114,5 +114,72 @@ namespace Avalonia.Controls.UnitTests Assert.False(window.IsVisible); } } + + [Fact] + public void Show_Should_Add_Window_To_OpenWindows() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var window = new Window(); + + window.Show(); + + Assert.Equal(new[] { window }, Window.OpenWindows); + + window.Close(); + } + } + + [Fact] + public void Window_Should_Be_Added_To_OpenWindows_Only_Once() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + 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)) + { + 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(); + 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)) + { + var window = new Window(); + + window.Show(); + windowImpl.Object.Closed(); + + Assert.Empty(Window.OpenWindows); + } + } } }