Skip to content

Commit

Permalink
add ClosingBehavior api to Window (#14621)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmauss authored Feb 18, 2024
1 parent bbef4bb commit 073a530
Showing 1 changed file with 62 additions and 17 deletions.
79 changes: 62 additions & 17 deletions src/Avalonia.Controls/Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,25 @@ public enum SystemDecorations
Full = 2
}

/// <summary>
/// Describes how the <see cref="Window.Closing"/> event behaves in the presence of child windows.
/// </summary>
public enum WindowClosingBehavior
{
/// <summary>
/// When the owner window is closed, the child windows' <see cref="Window.Closing"/> event
/// will be raised, followed by the owner window's <see cref="Window.Closing"/> events. A child
/// canceling the close will result in the owner Window's close being cancelled.
/// </summary>
OwnerAndChildWindows,

/// <summary>
/// When the owner window is closed, only the owner window's <see cref="Window.Closing"/> event
/// will be raised. This behavior is the same as WPF's.
/// </summary>
OwnerWindowOnly,
}

/// <summary>
/// A top-level window.
/// </summary>
Expand Down Expand Up @@ -127,6 +146,12 @@ public class Window : WindowBase, IFocusScope, ILayoutRoot
public static readonly StyledProperty<bool> ShowInTaskbarProperty =
AvaloniaProperty.Register<Window, bool>(nameof(ShowInTaskbar), true);

/// <summary>
/// Defines the <see cref="ClosingBehavior"/> property.
/// </summary>
public static readonly StyledProperty<WindowClosingBehavior> ClosingBehaviorProperty =
AvaloniaProperty.Register<Window, WindowClosingBehavior>(nameof(ClosingBehavior));

/// <summary>
/// Represents the current window state (normal, minimized, maximized)
/// </summary>
Expand Down Expand Up @@ -347,6 +372,16 @@ public bool ShowInTaskbar
set => SetValue(ShowInTaskbarProperty, value);
}

/// <summary>
/// Gets or sets a value indicating how the <see cref="Closing"/> event behaves in the presence
/// of child windows.
/// </summary>
public WindowClosingBehavior ClosingBehavior
{
get => GetValue(ClosingBehaviorProperty);
set => SetValue(ClosingBehaviorProperty, value);
}

/// <summary>
/// Gets or sets the minimized/maximized state of the window.
/// </summary>
Expand Down Expand Up @@ -487,31 +522,41 @@ private void CloseInternal()

private bool ShouldCancelClose(WindowClosingEventArgs args)
{
bool canClose = true;

if (_children.Count > 0)
switch (ClosingBehavior)
{
var childArgs = args.CloseReason == WindowCloseReason.WindowClosing ?
new WindowClosingEventArgs(WindowCloseReason.OwnerWindowClosing, args.IsProgrammatic) :
args;
case WindowClosingBehavior.OwnerAndChildWindows:
bool canClose = true;

foreach (var (child, _) in _children.ToArray())
{
if (child.ShouldCancelClose(childArgs))
if (_children.Count > 0)
{
canClose = false;
var childArgs = args.CloseReason == WindowCloseReason.WindowClosing ?
new WindowClosingEventArgs(WindowCloseReason.OwnerWindowClosing, args.IsProgrammatic) :
args;

foreach (var (child, _) in _children.ToArray())
{
if (child.ShouldCancelClose(childArgs))
{
canClose = false;
}
}
}
}
}

if (canClose)
{
OnClosing(args);
if (canClose)
{
OnClosing(args);

return args.Cancel;
return args.Cancel;
}

return true;
case WindowClosingBehavior.OwnerWindowOnly:
OnClosing(args);

return args.Cancel;
}

return true;
return false;
}

private void HandleWindowStateChanged(WindowState state)
Expand Down

0 comments on commit 073a530

Please sign in to comment.