У меня 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"
Я перепроверил это, но я уже установил владельца перед ShowDialog()
Итак, я думаю, мы говорим о модальном диалоге, верно? Не могли бы вы добавить минимальный воспроизводимый пример? Итак, мы можем видеть, как именно ваш Диалог относится к открывающейся Форме и что вы настраиваете, а что нет?
@TannerHall: не загружайте свой образец на внешний сайт. Разместите это здесь.
@ mm8 это, вероятно, вызовет ненависть, но я не нашел возможности загрузить zip-файл прямо сюда, и даже когда я проверял в Интернете, как это сделать - все, что я нашел, это то, что вы не можете, и люди говорили, что используйте Dropbox и т.п.
Вы не должны загружать ZIP-файл, но отредактируйте свой вопрос, включив в него фрагменты кода, составляющие MCVE.
@mm8 я отредактировал свой билет - спасибо
Когда вы щелкаете за пределами модального окна, управляемое событие не возникает, но вы должны иметь возможность обрабатывать это в модальном окне, используя некоторый 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
.
Похоже, вы не устанавливаете для свойства
Owner
B значение A?