|
|
|
@ -176,6 +176,8 @@ namespace Avalonia.Controls |
|
|
|
private object? _dialogResult; |
|
|
|
private readonly Size _maxPlatformClientSize; |
|
|
|
private WindowStartupLocation _windowStartupLocation; |
|
|
|
private bool _shown; |
|
|
|
private bool _showingAsDialog; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes static members of the <see cref="Window"/> class.
|
|
|
|
@ -508,6 +510,8 @@ namespace Avalonia.Controls |
|
|
|
Owner = null; |
|
|
|
|
|
|
|
PlatformImpl?.Dispose(); |
|
|
|
|
|
|
|
_showingAsDialog = false; |
|
|
|
} |
|
|
|
|
|
|
|
private bool ShouldCancelClose(CancelEventArgs? args = null) |
|
|
|
@ -563,29 +567,33 @@ namespace Avalonia.Controls |
|
|
|
/// </summary>
|
|
|
|
public override void Hide() |
|
|
|
{ |
|
|
|
if (!IsVisible) |
|
|
|
using (FreezeVisibilityChangeHandling()) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
if (!_shown) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
Renderer?.Stop(); |
|
|
|
Renderer?.Stop(); |
|
|
|
|
|
|
|
if (Owner is Window owner) |
|
|
|
{ |
|
|
|
owner.RemoveChild(this); |
|
|
|
} |
|
|
|
if (Owner is Window owner) |
|
|
|
{ |
|
|
|
owner.RemoveChild(this); |
|
|
|
} |
|
|
|
|
|
|
|
if (_children.Count > 0) |
|
|
|
{ |
|
|
|
foreach (var child in _children.ToArray()) |
|
|
|
if (_children.Count > 0) |
|
|
|
{ |
|
|
|
child.child.Hide(); |
|
|
|
foreach (var child in _children.ToArray()) |
|
|
|
{ |
|
|
|
child.child.Hide(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Owner = null; |
|
|
|
PlatformImpl?.Hide(); |
|
|
|
IsVisible = false; |
|
|
|
Owner = null; |
|
|
|
PlatformImpl?.Hide(); |
|
|
|
IsVisible = false; |
|
|
|
_shown = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -599,81 +607,124 @@ namespace Avalonia.Controls |
|
|
|
ShowCore(null); |
|
|
|
} |
|
|
|
|
|
|
|
protected override void IsVisibleChanged(AvaloniaPropertyChangedEventArgs e) |
|
|
|
{ |
|
|
|
if (!IgnoreVisibilityChanges) |
|
|
|
{ |
|
|
|
var isVisible = e.GetNewValue<bool>(); |
|
|
|
|
|
|
|
if (_shown != isVisible) |
|
|
|
{ |
|
|
|
if(!_shown) |
|
|
|
{ |
|
|
|
Show(); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (_showingAsDialog) |
|
|
|
{ |
|
|
|
Close(false); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
Hide(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Shows the window as a child of <paramref name="parent"/>.
|
|
|
|
/// Shows the window as a child of <paramref name="owner"/>.
|
|
|
|
/// </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">
|
|
|
|
/// The window has already been closed.
|
|
|
|
/// </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."); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void EnsureParentStateBeforeShow(Window owner) |
|
|
|
{ |
|
|
|
if (owner.PlatformImpl == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("Cannot show a window with a closed owner."); |
|
|
|
} |
|
|
|
|
|
|
|
if (parent != null) |
|
|
|
if (owner == this) |
|
|
|
{ |
|
|
|
if (parent.PlatformImpl == null) |
|
|
|
{ |
|
|
|
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."); |
|
|
|
} |
|
|
|
throw new InvalidOperationException("A Window cannot be its own owner."); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsVisible) |
|
|
|
if (!owner.IsVisible) |
|
|
|
{ |
|
|
|
return; |
|
|
|
throw new InvalidOperationException("Cannot show window with non-visible owner."); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
RaiseEvent(new RoutedEventArgs(WindowOpenedEvent)); |
|
|
|
private void ShowCore(Window? owner) |
|
|
|
{ |
|
|
|
using (FreezeVisibilityChangeHandling()) |
|
|
|
{ |
|
|
|
EnsureStateBeforeShow(); |
|
|
|
|
|
|
|
EnsureInitialized(); |
|
|
|
ApplyStyling(); |
|
|
|
IsVisible = true; |
|
|
|
if (owner != null) |
|
|
|
{ |
|
|
|
EnsureParentStateBeforeShow(owner); |
|
|
|
} |
|
|
|
|
|
|
|
var initialSize = new Size( |
|
|
|
double.IsNaN(Width) ? Math.Max(MinWidth, ClientSize.Width) : Width, |
|
|
|
double.IsNaN(Height) ? Math.Max(MinHeight, ClientSize.Height) : Height); |
|
|
|
if (_shown) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (initialSize != ClientSize) |
|
|
|
{ |
|
|
|
PlatformImpl?.Resize(initialSize, PlatformResizeReason.Layout); |
|
|
|
} |
|
|
|
RaiseEvent(new RoutedEventArgs(WindowOpenedEvent)); |
|
|
|
|
|
|
|
LayoutManager.ExecuteInitialLayoutPass(); |
|
|
|
EnsureInitialized(); |
|
|
|
ApplyStyling(); |
|
|
|
_shown = true; |
|
|
|
IsVisible = true; |
|
|
|
|
|
|
|
if (PlatformImpl != null && parent?.PlatformImpl is not null) |
|
|
|
{ |
|
|
|
PlatformImpl.SetParent(parent.PlatformImpl); |
|
|
|
} |
|
|
|
var initialSize = new Size( |
|
|
|
double.IsNaN(Width) ? Math.Max(MinWidth, ClientSize.Width) : Width, |
|
|
|
double.IsNaN(Height) ? Math.Max(MinHeight, ClientSize.Height) : Height); |
|
|
|
|
|
|
|
Owner = parent; |
|
|
|
parent?.AddChild(this, false); |
|
|
|
if (initialSize != ClientSize) |
|
|
|
{ |
|
|
|
PlatformImpl?.Resize(initialSize, PlatformResizeReason.Layout); |
|
|
|
} |
|
|
|
|
|
|
|
SetWindowStartupLocation(parent?.PlatformImpl); |
|
|
|
LayoutManager.ExecuteInitialLayoutPass(); |
|
|
|
|
|
|
|
PlatformImpl?.Show(ShowActivated, false); |
|
|
|
Renderer?.Start(); |
|
|
|
OnOpened(EventArgs.Empty); |
|
|
|
if (PlatformImpl != null && owner?.PlatformImpl is not null) |
|
|
|
{ |
|
|
|
PlatformImpl.SetParent(owner.PlatformImpl); |
|
|
|
} |
|
|
|
|
|
|
|
Owner = owner; |
|
|
|
owner?.AddChild(this, false); |
|
|
|
|
|
|
|
SetWindowStartupLocation(owner?.PlatformImpl); |
|
|
|
|
|
|
|
PlatformImpl?.Show(ShowActivated, false); |
|
|
|
Renderer?.Start(); |
|
|
|
OnOpened(EventArgs.Empty); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -703,68 +754,66 @@ namespace Avalonia.Controls |
|
|
|
/// </returns>
|
|
|
|
public Task<TResult> ShowDialog<TResult>(Window owner) |
|
|
|
{ |
|
|
|
if (owner == null) |
|
|
|
{ |
|
|
|
throw new ArgumentNullException(nameof(owner)); |
|
|
|
} |
|
|
|
else if (owner.PlatformImpl == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("Cannot show a window with a closed owner."); |
|
|
|
} |
|
|
|
else if (owner == this) |
|
|
|
using (FreezeVisibilityChangeHandling()) |
|
|
|
{ |
|
|
|
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."); |
|
|
|
} |
|
|
|
EnsureStateBeforeShow(); |
|
|
|
|
|
|
|
RaiseEvent(new RoutedEventArgs(WindowOpenedEvent)); |
|
|
|
if (owner == null) |
|
|
|
{ |
|
|
|
throw new ArgumentNullException(nameof(owner)); |
|
|
|
} |
|
|
|
|
|
|
|
EnsureInitialized(); |
|
|
|
ApplyStyling(); |
|
|
|
IsVisible = true; |
|
|
|
EnsureParentStateBeforeShow(owner); |
|
|
|
|
|
|
|
var initialSize = new Size( |
|
|
|
double.IsNaN(Width) ? ClientSize.Width : Width, |
|
|
|
double.IsNaN(Height) ? ClientSize.Height : Height); |
|
|
|
if (_shown) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("The window is already being shown."); |
|
|
|
} |
|
|
|
|
|
|
|
if (initialSize != ClientSize) |
|
|
|
{ |
|
|
|
PlatformImpl?.Resize(initialSize, PlatformResizeReason.Layout); |
|
|
|
} |
|
|
|
RaiseEvent(new RoutedEventArgs(WindowOpenedEvent)); |
|
|
|
|
|
|
|
LayoutManager.ExecuteInitialLayoutPass(); |
|
|
|
EnsureInitialized(); |
|
|
|
ApplyStyling(); |
|
|
|
_shown = true; |
|
|
|
_showingAsDialog = true; |
|
|
|
IsVisible = true; |
|
|
|
|
|
|
|
var result = new TaskCompletionSource<TResult>(); |
|
|
|
var initialSize = new Size( |
|
|
|
double.IsNaN(Width) ? ClientSize.Width : Width, |
|
|
|
double.IsNaN(Height) ? ClientSize.Height : Height); |
|
|
|
|
|
|
|
PlatformImpl?.SetParent(owner.PlatformImpl); |
|
|
|
Owner = owner; |
|
|
|
owner.AddChild(this, true); |
|
|
|
if (initialSize != ClientSize) |
|
|
|
{ |
|
|
|
PlatformImpl?.Resize(initialSize, PlatformResizeReason.Layout); |
|
|
|
} |
|
|
|
|
|
|
|
SetWindowStartupLocation(owner.PlatformImpl); |
|
|
|
LayoutManager.ExecuteInitialLayoutPass(); |
|
|
|
|
|
|
|
PlatformImpl?.Show(ShowActivated, true); |
|
|
|
var result = new TaskCompletionSource<TResult>(); |
|
|
|
|
|
|
|
Renderer?.Start(); |
|
|
|
PlatformImpl?.SetParent(owner.PlatformImpl!); |
|
|
|
Owner = owner; |
|
|
|
owner.AddChild(this, true); |
|
|
|
|
|
|
|
Observable.FromEventPattern<EventHandler, EventArgs>( |
|
|
|
x => Closed += x, |
|
|
|
x => Closed -= x) |
|
|
|
.Take(1) |
|
|
|
.Subscribe(_ => |
|
|
|
{ |
|
|
|
owner.Activate(); |
|
|
|
result.SetResult((TResult)(_dialogResult ?? default(TResult)!)); |
|
|
|
}); |
|
|
|
SetWindowStartupLocation(owner.PlatformImpl); |
|
|
|
|
|
|
|
OnOpened(EventArgs.Empty); |
|
|
|
return result.Task; |
|
|
|
PlatformImpl?.Show(ShowActivated, true); |
|
|
|
|
|
|
|
Renderer?.Start(); |
|
|
|
|
|
|
|
Observable.FromEventPattern<EventHandler, EventArgs>( |
|
|
|
x => Closed += x, |
|
|
|
x => Closed -= x) |
|
|
|
.Take(1) |
|
|
|
.Subscribe(_ => |
|
|
|
{ |
|
|
|
owner.Activate(); |
|
|
|
result.SetResult((TResult)(_dialogResult ?? default(TResult)!)); |
|
|
|
}); |
|
|
|
|
|
|
|
OnOpened(EventArgs.Empty); |
|
|
|
return result.Task; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void UpdateEnabled() |
|
|
|
|