Browse Source

fix window showdialog, and show raising exceptions when incorrect behavior is used.

pull/9562/head
Dan Walmsley 4 years ago
parent
commit
1af7eb6f3a
  1. 99
      src/Avalonia.Controls/Window.cs
  2. 8
      tests/Avalonia.Controls.UnitTests/WindowTests.cs

99
src/Avalonia.Controls/Window.cs

@ -641,47 +641,64 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Shows the window as a child of <paramref name="parent"/>. /// Shows the window as a child of <paramref name="owner"/>.
/// </summary> /// </summary>
/// <param name="parent">Window that will be a parent of the shown window.</param> /// <param name="owner">Window that will be the owner of the shown window.</param>
/// <exception cref="InvalidOperationException"> /// <exception cref="InvalidOperationException">
/// The window has already been closed. /// The window has already been closed.
/// </exception> /// </exception>
public void Show(Window parent) public void Show(Window owner)
{ {
if (parent is null) if (owner is null)
{ {
throw new ArgumentNullException(nameof(parent), "Showing a child window requires valid parent."); throw new ArgumentNullException(nameof(owner), "Showing a child window requires valid parent.");
} }
ShowCore(parent); ShowCore(owner);
} }
private void ShowCore(Window? parent) private void EnsureStateBeforeShow()
{
if (PlatformImpl == null)
{
throw new InvalidOperationException("Cannot re-show a closed window.");
}
if (_shown)
{
throw new InvalidOperationException("The window is already being shown.");
}
}
private void EnsureParentStateBeforeShow(Window owner)
{
if (owner.PlatformImpl == null)
{
throw new InvalidOperationException("Cannot show a window with a closed owner.");
}
if (owner == this)
{
throw new InvalidOperationException("A Window cannot be its own owner.");
}
if (!owner.IsVisible)
{
throw new InvalidOperationException("Cannot show window with non-visible owner.");
}
}
private void ShowCore(Window? owner)
{ {
try try
{ {
IgnoreVisibilityChange = true; IgnoreVisibilityChange = true;
if (PlatformImpl == null)
{
throw new InvalidOperationException("Cannot re-show a closed window.");
}
if (parent != null) EnsureStateBeforeShow();
if (owner != null)
{ {
if (parent.PlatformImpl == null) EnsureParentStateBeforeShow(owner);
{
throw new InvalidOperationException("Cannot show a window with a closed parent.");
}
else if (parent == this)
{
throw new InvalidOperationException("A Window cannot be its own parent.");
}
else if (!parent.IsVisible)
{
throw new InvalidOperationException("Cannot show window with non-visible parent.");
}
} }
if (_shown) if (_shown)
@ -707,15 +724,15 @@ namespace Avalonia.Controls
LayoutManager.ExecuteInitialLayoutPass(); LayoutManager.ExecuteInitialLayoutPass();
if (PlatformImpl != null && parent?.PlatformImpl is not null) if (PlatformImpl != null && owner?.PlatformImpl is not null)
{ {
PlatformImpl.SetParent(parent.PlatformImpl); PlatformImpl.SetParent(owner.PlatformImpl);
} }
Owner = parent; Owner = owner;
parent?.AddChild(this, false); owner?.AddChild(this, false);
SetWindowStartupLocation(parent?.PlatformImpl); SetWindowStartupLocation(owner?.PlatformImpl);
PlatformImpl?.Show(ShowActivated, false); PlatformImpl?.Show(ShowActivated, false);
Renderer?.Start(); Renderer?.Start();
@ -758,26 +775,14 @@ namespace Avalonia.Controls
{ {
IgnoreVisibilityChange = true; IgnoreVisibilityChange = true;
EnsureStateBeforeShow();
if (owner == null) if (owner == null)
{ {
throw new ArgumentNullException(nameof(owner)); throw new ArgumentNullException(nameof(owner));
} }
else if (owner.PlatformImpl == null)
{ EnsureParentStateBeforeShow(owner);
throw new InvalidOperationException("Cannot show a window with a closed owner.");
}
else if (owner == this)
{
throw new InvalidOperationException("A Window cannot be its own owner.");
}
else if (IsVisible)
{
throw new InvalidOperationException("The window is already being shown.");
}
else if (!owner.IsVisible)
{
throw new InvalidOperationException("Cannot show window with non-visible parent.");
}
RaiseEvent(new RoutedEventArgs(WindowOpenedEvent)); RaiseEvent(new RoutedEventArgs(WindowOpenedEvent));
@ -800,7 +805,7 @@ namespace Avalonia.Controls
var result = new TaskCompletionSource<TResult>(); var result = new TaskCompletionSource<TResult>();
PlatformImpl?.SetParent(owner.PlatformImpl); PlatformImpl?.SetParent(owner.PlatformImpl!);
Owner = owner; Owner = owner;
owner.AddChild(this, true); owner.AddChild(this, true);

8
tests/Avalonia.Controls.UnitTests/WindowTests.cs

@ -403,7 +403,7 @@ namespace Avalonia.Controls.UnitTests
parent.Close(); parent.Close();
var ex = Assert.Throws<InvalidOperationException>(() => target.Show(parent)); var ex = Assert.Throws<InvalidOperationException>(() => target.Show(parent));
Assert.Equal("Cannot show a window with a closed parent.", ex.Message); Assert.Equal("Cannot show a window with a closed owner.", ex.Message);
} }
} }
@ -431,7 +431,7 @@ namespace Avalonia.Controls.UnitTests
var target = new Window(); var target = new Window();
var ex = Assert.Throws<InvalidOperationException>(() => target.Show(parent)); var ex = Assert.Throws<InvalidOperationException>(() => target.Show(parent));
Assert.Equal("Cannot show window with non-visible parent.", ex.Message); Assert.Equal("Cannot show window with non-visible owner.", ex.Message);
} }
} }
@ -444,7 +444,7 @@ namespace Avalonia.Controls.UnitTests
var target = new Window(); var target = new Window();
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog(parent)); var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog(parent));
Assert.Equal("Cannot show window with non-visible parent.", ex.Message); Assert.Equal("Cannot show window with non-visible owner.", ex.Message);
} }
} }
@ -456,7 +456,7 @@ namespace Avalonia.Controls.UnitTests
var target = new Window(); var target = new Window();
var ex = Assert.Throws<InvalidOperationException>(() => target.Show(target)); var ex = Assert.Throws<InvalidOperationException>(() => target.Show(target));
Assert.Equal("A Window cannot be its own parent.", ex.Message); Assert.Equal("A Window cannot be its own owner.", ex.Message);
} }
} }

Loading…
Cancel
Save