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

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

Я пытаюсь вывести блокирующее окно B на передний план, когда он пытается получить доступ к окну A с открытым окном B.

Пример кода:

Вот как окно А открывается из главного окна

            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"

Похоже, вы не устанавливаете для свойства Owner B значение A?

Mark Feldman 02.05.2019 11:04

Я перепроверил это, но я уже установил владельца перед ShowDialog()

Tanner Hall 02.05.2019 11:13

Итак, я думаю, мы говорим о модальном диалоге, верно? Не могли бы вы добавить минимальный воспроизводимый пример? Итак, мы можем видеть, как именно ваш Диалог относится к открывающейся Форме и что вы настраиваете, а что нет?

Fildor 02.05.2019 11:42
filedropper.com/sotestapp Я загрузил сюда тестовое приложение. Вы можете просто щелкнуть среднюю кнопку в приложении -> затем свернуть окно B, а затем снова открыть окно A. Теперь окно A блокируется, и я хочу снова показать B, когда блокируется A
Tanner Hall 02.05.2019 12:50

@TannerHall: не загружайте свой образец на внешний сайт. Разместите это здесь.

mm8 02.05.2019 15:28

@ mm8 это, вероятно, вызовет ненависть, но я не нашел возможности загрузить zip-файл прямо сюда, и даже когда я проверял в Интернете, как это сделать - все, что я нашел, это то, что вы не можете, и люди говорили, что используйте Dropbox и т.п.

Tanner Hall 02.05.2019 15:39

Вы не должны загружать ZIP-файл, но отредактируйте свой вопрос, включив в него фрагменты кода, составляющие MCVE.

mm8 02.05.2019 15:43

@mm8 я отредактировал свой билет - спасибо

Tanner Hall 02.05.2019 15:53
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
8
138
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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

Другие вопросы по теме