7 changed files with 428 additions and 49 deletions
@ -0,0 +1,12 @@ |
|||
// 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.
|
|||
|
|||
namespace Avalonia |
|||
{ |
|||
public enum ExitMode |
|||
{ |
|||
OnLastWindowClose, |
|||
OnMainWindowClose, |
|||
OnExplicitExit |
|||
} |
|||
} |
|||
@ -0,0 +1,134 @@ |
|||
// 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.Collections; |
|||
using System.Collections.Generic; |
|||
|
|||
using Avalonia.Controls; |
|||
|
|||
namespace Avalonia |
|||
{ |
|||
public class WindowCollection : IReadOnlyList<Window> |
|||
{ |
|||
private readonly Application _application; |
|||
private readonly List<Window> _windows = new List<Window>(); |
|||
|
|||
public WindowCollection(Application application) |
|||
{ |
|||
_application = application; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
/// <summary>
|
|||
/// Gets the number of elements in the collection.
|
|||
/// </summary>
|
|||
public int Count => _windows.Count; |
|||
|
|||
/// <inheritdoc />
|
|||
/// <summary>
|
|||
/// Gets the <see cref="T:Avalonia.Controls.Window" /> at the specified index.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The <see cref="T:Avalonia.Controls.Window" />.
|
|||
/// </value>
|
|||
/// <param name="index">The index.</param>
|
|||
/// <returns></returns>
|
|||
public Window this[int index] => _windows[index]; |
|||
|
|||
/// <inheritdoc />
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through the collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An enumerator that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
public IEnumerator<Window> GetEnumerator() |
|||
{ |
|||
return _windows.GetEnumerator(); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through a collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return GetEnumerator(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds the specified window.
|
|||
/// </summary>
|
|||
/// <param name="window">The window.</param>
|
|||
internal void Add(Window window) |
|||
{ |
|||
if (window == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
_windows.Add(window); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Removes the specified window.
|
|||
/// </summary>
|
|||
/// <param name="window">The window.</param>
|
|||
internal void Remove(Window window) |
|||
{ |
|||
if (window == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
_windows.Remove(window); |
|||
|
|||
OnRemoveWindow(window); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Closes all windows and removes them from the underlying collection.
|
|||
/// </summary>
|
|||
internal void Clear() |
|||
{ |
|||
while (_windows.Count > 0) |
|||
{ |
|||
_windows[0].Close(); |
|||
} |
|||
} |
|||
|
|||
private void OnRemoveWindow(Window window) |
|||
{ |
|||
if (window == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (_application.IsExiting) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
switch (_application.ExitMode) |
|||
{ |
|||
case ExitMode.OnLastWindowClose: |
|||
if (Count == 0) |
|||
{ |
|||
_application.Exit(); |
|||
} |
|||
|
|||
break; |
|||
case ExitMode.OnMainWindowClose: |
|||
if (window == _application.MainWindow) |
|||
{ |
|||
_application.Exit(); |
|||
} |
|||
|
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,107 @@ |
|||
// 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.Collections.Generic; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Controls.UnitTests |
|||
{ |
|||
public class ApplicationTests |
|||
{ |
|||
[Fact] |
|||
public void Should_Exit_After_MainWindow_Closed() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|||
{ |
|||
Application.Current.ExitMode = ExitMode.OnMainWindowClose; |
|||
|
|||
var mainWindow = new Window(); |
|||
|
|||
mainWindow.Show(); |
|||
|
|||
Application.Current.MainWindow = mainWindow; |
|||
|
|||
var window = new Window(); |
|||
|
|||
window.Show(); |
|||
|
|||
mainWindow.Close(); |
|||
|
|||
Assert.True(Application.Current.IsExiting); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Exit_After_Last_Window_Closed() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|||
{ |
|||
Application.Current.ExitMode = ExitMode.OnLastWindowClose; |
|||
|
|||
var windowA = new Window(); |
|||
|
|||
windowA.Show(); |
|||
|
|||
var windowB = new Window(); |
|||
|
|||
windowB.Show(); |
|||
|
|||
windowA.Close(); |
|||
|
|||
Assert.False(Application.Current.IsExiting); |
|||
|
|||
windowB.Close(); |
|||
|
|||
Assert.True(Application.Current.IsExiting); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Only_Exit_On_Explicit_Exit() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|||
{ |
|||
Application.Current.ExitMode = ExitMode.OnExplicitExit; |
|||
|
|||
var windowA = new Window(); |
|||
|
|||
windowA.Show(); |
|||
|
|||
var windowB = new Window(); |
|||
|
|||
windowB.Show(); |
|||
|
|||
windowA.Close(); |
|||
|
|||
Assert.False(Application.Current.IsExiting); |
|||
|
|||
windowB.Close(); |
|||
|
|||
Assert.False(Application.Current.IsExiting); |
|||
|
|||
Application.Current.Exit(); |
|||
|
|||
Assert.True(Application.Current.IsExiting); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Close_All_Remaining_Open_Windows_After_Explicit_Exit_Call() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|||
{ |
|||
var windows = new List<Window> { new Window(), new Window(), new Window(), new Window() }; |
|||
|
|||
foreach (var window in windows) |
|||
{ |
|||
window.Show(); |
|||
} |
|||
|
|||
Application.Current.Exit(); |
|||
|
|||
Assert.Empty(Application.Current.Windows); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue