强制从代码中关闭所有打开的弹出窗口

Chr*_*col 4 c# wpf xaml

我想让所有打开的弹出窗口(使用StaysOpen == false)从代码中关闭.基本上我想模拟用户从代码中单击鼠标(这将关闭弹出窗口).

我不需要实际模拟点击,我只需要产生的行为.我想过只是通过视觉树寻找弹出窗口并关闭每个弹出窗口,但这似乎不是最干净的方法.

提前感谢任何帮助或意见.

Tho*_*que 9

WPF弹出窗口实际上创建了一个新窗口(Win32窗口,而不是WPF Window实例).所以你无法在Application.Windows集合中找到它,但你可以使用类似的Win32 API找到它EnumChildWindows.

获得句柄后,您可以检索关联的句柄HwndSource.我想RootVisualHwndSourcePopup(没有检查,你可能在可视化树看起来更深).

所以代码应该与此类似(完全未经测试):

public static class PopupCloser
{
    public static void CloseAllPopups()
    {
        foreach(Window window in Application.Current.Windows)
        {
            CloseAllPopups(window);
        }
    }

    public static void CloseAllPopups(Window window)
    {
        IntPtr handle = new WindowInteropHelper(window).Handle;
        EnumChildWindows(handle, ClosePopup, IntPtr.Zero);
    }

    private static bool ClosePopup(IntPtr hwnd, IntPtr lParam)
    {
        HwndSource source = HwndSource.FromHwnd(hwnd);
        if (source != null)
        {
            Popup popup = source.RootVisual as Popup;
            if (popup != null)
            {
                popup.IsOpen = false;
            }
        }
        return true; // to continue enumeration
    }

    private delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);

}
Run Code Online (Sandbox Code Playgroud)

  • 我无法让EnumChildWindows工作并最终使用EnumThreadWindows. (2认同)