我有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"
答案 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
。