diff --git a/samples/ControlCatalog/Pages/ContextFlyoutPage.xaml b/samples/ControlCatalog/Pages/ContextFlyoutPage.xaml
index b54b3fbdbf..cc17d9c747 100644
--- a/samples/ControlCatalog/Pages/ContextFlyoutPage.xaml
+++ b/samples/ControlCatalog/Pages/ContextFlyoutPage.xaml
@@ -78,12 +78,13 @@
-
+
+
+
-
diff --git a/samples/ControlCatalog/Pages/ContextMenuPage.xaml b/samples/ControlCatalog/Pages/ContextMenuPage.xaml
index 801e4a6c20..7e564efafc 100644
--- a/samples/ControlCatalog/Pages/ContextMenuPage.xaml
+++ b/samples/ControlCatalog/Pages/ContextMenuPage.xaml
@@ -71,13 +71,16 @@
-
+
-
diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs
index 57e4909e39..ca55fd0bc7 100644
--- a/src/Avalonia.Controls/ContextMenu.cs
+++ b/src/Avalonia.Controls/ContextMenu.cs
@@ -329,6 +329,7 @@ namespace Avalonia.Controls
_popup.Opened += PopupOpened;
_popup.Closed += PopupClosed;
+ _popup.Closing += PopupClosing;
}
if (_popup.Parent != control)
@@ -355,6 +356,11 @@ namespace Avalonia.Controls
Focus();
}
+ private void PopupClosing(object sender, CancelEventArgs e)
+ {
+ e.Cancel = CancelClosing();
+ }
+
private void PopupClosed(object sender, EventArgs e)
{
foreach (var i in LogicalChildren)
diff --git a/src/Avalonia.Controls/Flyouts/FlyoutBase.cs b/src/Avalonia.Controls/Flyouts/FlyoutBase.cs
index e4b68c62fd..011af4e7a5 100644
--- a/src/Avalonia.Controls/Flyouts/FlyoutBase.cs
+++ b/src/Avalonia.Controls/Flyouts/FlyoutBase.cs
@@ -151,11 +151,7 @@ namespace Avalonia.Controls.Primitives
if (canCancel)
{
- bool cancel = false;
-
- var closing = new CancelEventArgs();
- Closing?.Invoke(this, closing);
- if (cancel || closing.Cancel)
+ if (CancelClosing())
{
return;
}
@@ -195,6 +191,11 @@ namespace Avalonia.Controls.Primitives
}
}
+ if (CancelOpening())
+ {
+ return;
+ }
+
if (Popup.Parent != null && Popup.Parent != placementTarget)
{
((ISetLogicalParent)Popup).SetParent(null);
@@ -328,6 +329,7 @@ namespace Avalonia.Controls.Primitives
Popup.Opened += OnPopupOpened;
Popup.Closed += OnPopupClosed;
+ Popup.Closing += OnPopupClosing;
}
private void OnPopupOpened(object sender, EventArgs e)
@@ -335,9 +337,14 @@ namespace Avalonia.Controls.Primitives
IsOpen = true;
}
+ private void OnPopupClosing(object sender, CancelEventArgs e)
+ {
+ e.Cancel = CancelClosing();
+ }
+
private void OnPopupClosed(object sender, EventArgs e)
{
- HideCore();
+ HideCore(false);
}
private void PositionPopup(bool showAtPointer)
@@ -483,6 +490,20 @@ namespace Avalonia.Controls.Primitives
}
}
+ private bool CancelClosing()
+ {
+ var eventArgs = new CancelEventArgs();
+ Closing?.Invoke(this, eventArgs);
+ return eventArgs.Cancel;
+ }
+
+ private bool CancelOpening()
+ {
+ var eventArgs = new CancelEventArgs();
+ Opening?.Invoke(this, eventArgs);
+ return eventArgs.Cancel;
+ }
+
internal static void SetPresenterClasses(IControl presenter, Classes classes)
{
//Remove any classes no longer in use, ignoring pseudoclasses
diff --git a/src/Avalonia.Controls/Primitives/Popup.cs b/src/Avalonia.Controls/Primitives/Popup.cs
index b445de0472..f23a27e67a 100644
--- a/src/Avalonia.Controls/Primitives/Popup.cs
+++ b/src/Avalonia.Controls/Primitives/Popup.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using System.Linq;
using System.Reactive.Disposables;
using Avalonia.Controls.Presenters;
@@ -154,6 +155,8 @@ namespace Avalonia.Controls.Primitives
///
public event EventHandler? Opened;
+ internal event EventHandler? Closing;
+
public IPopupHost? Host => _openState?.PopupHost;
public bool WindowManagerAddShadowHint
@@ -567,6 +570,13 @@ namespace Avalonia.Controls.Primitives
private void CloseCore()
{
+ var closingArgs = new CancelEventArgs();
+ Closing?.Invoke(this, closingArgs);
+ if (closingArgs.Cancel)
+ {
+ return;
+ }
+
_isOpenRequested = false;
if (_openState is null)
{