Browse Source

Fix popups not closing when using WinForms Host (#20090)

* fix popups not closing in embedded view in winforms

* fix winforms integration test sample

* addressed review
pull/19927/merge
Emmanuel Hansen 3 months ago
committed by GitHub
parent
commit
8631917d57
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 18
      src/Avalonia.Controls/Primitives/Popup.cs
  2. 27
      src/Windows/Avalonia.Win32.Interoperability/WinForms/WinFormsAvaloniaControlHost.cs
  3. 2
      src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

18
src/Avalonia.Controls/Primitives/Popup.cs

@ -536,6 +536,16 @@ namespace Avalonia.Controls.Primitives
(x, handler) => x.Closed -= handler).DisposeWith(handlerCleanup);
}
}
else if (topLevel is { } wtl && wtl.PlatformImpl is IWindowBaseImpl wimpl)
{
SubscribeToEventHandler<ITopLevelImpl, Action>(wimpl, TopLevelLostPlatformFocus,
(x, handler) => x.LostFocus += handler,
(x, handler) => x.LostFocus -= handler).DisposeWith(handlerCleanup);
SubscribeToEventHandler<IWindowBaseImpl, Action>(wimpl, WindowBaseDeactivated,
(x, handler) => x.Deactivated += handler,
(x, handler) => x.Deactivated -= handler).DisposeWith(handlerCleanup);
}
else if (topLevel is { } tl && tl.PlatformImpl is ITopLevelImpl pimpl)
{
SubscribeToEventHandler<ITopLevelImpl, Action>(pimpl, TopLevelLostPlatformFocus,
@ -987,6 +997,14 @@ namespace Avalonia.Controls.Primitives
}
}
private void WindowBaseDeactivated()
{
if (IsLightDismissEnabled)
{
Close();
}
}
private void ParentClosed(object? sender, EventArgs e)
{
if (IsLightDismissEnabled)

27
src/Windows/Avalonia.Win32.Interoperability/WinForms/WinFormsAvaloniaControlHost.cs

@ -14,7 +14,7 @@ namespace Avalonia.Win32.Interoperability;
/// An element that allows you to host a Avalonia control on a Windows Forms page.
/// </summary>
[ToolboxItem(true)]
public class WinFormsAvaloniaControlHost : WinFormsControl
public class WinFormsAvaloniaControlHost : WinFormsControl, IMessageFilter
{
private AvControl? _content;
private EmbeddableControlRoot? _root;
@ -66,11 +66,14 @@ public class WinFormsAvaloniaControlHost : WinFormsControl
}
base.OnHandleCreated(e);
System.Windows.Forms.Application.AddMessageFilter(this);
}
/// <inheritdoc />
protected override void OnHandleDestroyed(EventArgs e)
{
System.Windows.Forms.Application.RemoveMessageFilter(this);
_root?.StopRendering();
_root?.Dispose();
_root = null;
@ -135,4 +138,26 @@ public class WinFormsAvaloniaControlHost : WinFormsControl
e.Graphics.DrawString(message, Font, SystemBrushes.ControlText, messageArea);
}
}
public bool PreFilterMessage(ref Message m)
{
var message = (UnmanagedMethods.WindowsMessage)m.Msg;
switch (message)
{
case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN:
case UnmanagedMethods.WindowsMessage.WM_MBUTTONDOWN:
case UnmanagedMethods.WindowsMessage.WM_RBUTTONDOWN:
case UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN:
case UnmanagedMethods.WindowsMessage.WM_NCMBUTTONDOWN:
case UnmanagedMethods.WindowsMessage.WM_NCRBUTTONDOWN:
if (_root?.PlatformImpl is WindowImpl impl && !impl.IsOurWindow(m.HWnd))
{
impl.Deactivated?.Invoke();
}
break;
}
return false;
}
}

2
src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

@ -900,7 +900,7 @@ namespace Avalonia.Win32
return DefWindowProc(hWnd, msg, wParam, lParam);
}
private bool IsOurWindow(IntPtr hwnd)
internal bool IsOurWindow(IntPtr hwnd)
{
if (hwnd == IntPtr.Zero)
return false;

Loading…
Cancel
Save