Есть ли событие или что-то, что я могу использовать, когда showdialogwindow блокирует окно, к которому я пытаюсь получить доступ? - PullRequest
4 голосов
/ 02 мая 2019

У меня 2 окна.Давайте назовем их A и B. A открывает B с помощью ShowDialog ().Итак, я открываю B - когда пользователь сворачивает B или каким-то образом возвращает его в спину и пытается снова щелкнуть окно A, чтобы оно заблокировалось (как и должно быть), но есть ли событие, на которое я могу догнать, когда это произойдет?

Я пытаюсь вывести блокирующее окно 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 ]

1 голос
/ 03 мая 2019

Если вы хотите восстановить второе окно, когда оно свернуто и пользователь нажимает на первое (заблокированное) окно, то вы можете пойти по этому пути (добавить этот код в 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), что вы должны предотвратить.

Левая кнопка мыши на WindowA восстанавливает затем WindowB.

1 голос
/ 02 мая 2019

Управляемое событие не вызывается, когда вы щелкаете за пределами модального окна, но вы должны быть в состоянии обработать это в модальном окне с помощью некоторого вызова 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);
    }
}
...