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

时间:2019-05-02 09:01:05

标签: c# wpf windows window showdialog

我有2个窗口。我们称它们为A和B。 A用ShowDialog()打开B。 因此,我正在打开B-当用户最小化B或以某种方式将其放回后方并且他再次尝试单击窗口A时,它被阻塞了(应该是),但是发生这种情况时我是否可以追上一个事件? / p>

当他尝试在打开窗口B的情况下访问窗口A时,我试图将阻止窗口B置于最前面。

代码示例:

这就是从主窗口打开窗口A的方式

            WindowA windowA = new WindowA();

            windowA.Owner = Application.Current.MainWindow;

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

这就是打开窗口B的方式

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

两个窗口都没有设置任何特殊属性,除了

WindowStartupLocation="CenterScreen"

2 个答案:

答案 0 :(得分:1)

当您在模态窗口之外单击时,不会引发任何托管事件,但是您应该能够使用一些p / invoke在模态窗口中处理此事件。这是给您的示例:

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);
    }
}

答案 1 :(得分:1)

如果要在最小化后恢复第二个窗口并且用户确实单击第一个(被阻止的)窗口,则可以采用这种方式(将此代码添加到Fragment中):

ViewModel

因此,您必须在最小化的第二个窗口上开始捕获鼠标,因为如果用户单击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"); } 上进行处理。
由于窗口被最小化,因此将丢失鼠标捕获(因此您必须在WindowA上进行监听),因此必须避免。

WindowB上的鼠标左键确实会恢复LostMouseCapture