当 showdialogwindow 阻止我尝试访问的 window 时,是否有事件或我可以使用的东西

Is there an event or something i can use when a showdialogwindow is blocking the window i try to access

我有 2 个windows。让我们称它们为 A 和 B。 A 正在使用 ShowDialog() 打开 B。 所以我打开 B - 当用户最小化 B 或以某种方式将它放到后面并且他尝试再次单击 window A 时它被阻止了(应该如此),但是是否有一个事件我可以在什么时候赶上发生这种情况?

当他试图访问 window A 并打开 window B 时,我正在努力实现将阻塞 window B 置于前面。

代码示例:

这就是 Window A 从 Main 打开的方式window

            WindowA windowA = new WindowA();

            windowA.Owner = Application.Current.MainWindow;

            windowA.Show();
            windowA.Activate();

这就是 Window B 的打开方式

            WindowB windowB = new WindowB();
            windowB.Owner = this; //(this = windowA)
            windowB.ShowDialog();

除了

,windows都没有设置特殊属性
WindowStartupLocation="CenterScreen"

当您在模态 window 外部单击时,不会引发任何托管事件,但您应该能够使用某些 p/invoke 在模态 window 中处理此事件。这是一个例子:

public sealed partial class ModalWindow : Window, IDisposable
{
    [DllImport("User32.dll")]
    public static extern IntPtr SetWindowsHookEx(int idHook, HookDelegate lpfn, IntPtr hmod, int dwThreadId);

    [DllImport("User32.dll")]
    public static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("User32.dll")]
    public static extern IntPtr UnhookWindowsHookEx(IntPtr hHook);

    [DllImport("user32.dll")]
    public static extern bool GetCursorPos(out POINT lpPoint);

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;

        public static implicit operator Point(POINT point)
        {
            return new Point(point.X, point.Y);
        }
    }

    public delegate IntPtr HookDelegate(int code, IntPtr wParam, IntPtr lParam);

    private const int WH_MOUSE_LL = 14;
    private const int WM_LBUTTONDOWN = 0x0201;
    private HookDelegate mouseDelegate;
    private IntPtr mouseHandle;

    public ModalWindow()
    {
        InitializeComponent();
        mouseDelegate = MouseHookDelegate;
        mouseHandle = SetWindowsHookEx(WH_MOUSE_LL, mouseDelegate, IntPtr.Zero, 0);
    }

    private IntPtr MouseHookDelegate(int code, IntPtr wParam, IntPtr lParam)
    {
        if (code < 0)
            return CallNextHookEx(mouseHandle, code, wParam, lParam);

        switch ((int)wParam)
        {
            case WM_LBUTTONDOWN:
                POINT lpPoint;
                GetCursorPos(out lpPoint);
                if (lpPoint.X < Left || lpPoint.X > (Left + Width) || lpPoint.Y < Top || lpPoint.Y > (Top + Height))
                {
                    //Outside click detected...
                }
                break;
        }

        return CallNextHookEx(mouseHandle, code, wParam, lParam);
    }

    protected override void OnClosed(EventArgs e)
    {
        Dispose();
        base.OnClosed(e);
    }

    public void Dispose()
    {
        if (mouseHandle != IntPtr.Zero)
            UnhookWindowsHookEx(mouseHandle);
    }
}

如果你想在第二个 window 最小化并且用户点击第一个(阻塞)window 时恢复它,那么你可以这样做(将此代码添加到 WindowB):

public WindowB()
{
    PreviewMouseDown += WindowB_PreviewMouseDown;
    StateChanged += WindowB_StateChanged;
    InitializeComponent();
    LostMouseCapture += WindowB_LostMouseCapture;

}

private void WindowB_LostMouseCapture(object sender, MouseEventArgs e)
{
    //You can also evaluate here a mouse coordinates.
    if (WindowState == WindowState.Minimized)
    {
        e.Handled = true;
        CaptureMouse();
    }
}

private void WindowB_StateChanged(object sender, EventArgs e)
{
    if (WindowState== WindowState.Minimized)
    {
        CaptureMouse();
    }
    else
    {
        ReleaseMouseCapture();
    }
}

private void WindowB_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    WindowState = WindowState.Normal;
    Debug.WriteLine("WindowB PreviewMouseDown");
}

所以你必须在第二个 window 开始鼠标捕获,因为如果用户点击 WindowA 这可以在 WindowB.[=23= 上处理] 由于 window 被最小化,它会丢失鼠标捕获(因此你必须在 LostMouseCapture 上监听),你必须防止。

WindowA 上按下鼠标左键会恢复 WindowB