禁用WPF窗口焦点

我有一个WPF窗口,只有当您通过Visibility.Hidden和Visibility.Visible按住Tab键时才会显示。 但是,按住该键可将焦点从活动应用程序转移到WPF窗口。 我可以禁用此行为吗? 更进一步:是否可以完全防止窗口即使在单击控件时聚焦,但仍然注册控件的单击操作?

在其他地方找到答案:

protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); //Set the window style to noactivate. WindowInteropHelper helper = new WindowInteropHelper(this); SetWindowLong(helper.Handle, GWL_EXSTYLE, GetWindowLong(helper.Handle, GWL_EXSTYLE) | WS_EX_NOACTIVATE); } private const int GWL_EXSTYLE = -20; private const int WS_EX_NOACTIVATE = 0x08000000; [DllImport("user32.dll")] public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

由于.NET 3.5 SP1 WPF表单具有ShowActivated属性。 将此设置为false ,这样标记的表单不会再没有重点。

防止在WPF中激活某些顶级窗口

我尝试了这里给出的Win32解决方案,但它对我不起作用。 虽然它似乎确实阻止了窗口“激活”,但之后Focus处于不确定状态,而不是恢复到应用程序中的另一个合格窗口。 相反,以下工作对我有用:

首先,确保所有非主窗口的Owner属性都设置为主Window 。 我在子窗口的构造函数中执行此操作,在这种情况下,必须执行一些步骤(此处未讨论)以确保首先加载主Window

 public MySubWindow() { if ((base.Owner = Application.Current.MainWindow) == null) throw new Exception(); InitializeComponent(); } 

设置Owner属性还应确保子窗口保持在主窗口的顶部。 对于子窗口,按指示设置以下属性(XAML或代码):

  ShowActivated="False" Focusable="False" ShowInTaskbar="False" IsEnabled="False" FocusManager.IsFocusScope="False" 

最后,将OnActivated的处理程序添加到被阻止的窗口。 我没有调用基本方法,因为它触发了Activated事件。 (请注意,您不应将激活从Visual Studio设计器切换,因为它会使窗口不可见)。

 protected override void OnActivated(EventArgs e) { if (DesignerProperties.GetIsInDesignMode(this)) return; base.Owner.Activate(); } 

您可以通过添加自定义WndProc并处理WM_MOUSEACTIVATE来阻止WPF窗口在鼠标单击时激活:

  protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); var source = PresentationSource.FromVisual(this) as HwndSource; source.AddHook(WndProc); } private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WM_MOUSEACTIVATE) { handled = true; return new IntPtr(MA_NOACTIVATE); } else { return IntPtr.Zero; } } private const int WM_MOUSEACTIVATE = 0x0021; private const int MA_NOACTIVATE = 0x0003; 

参考文献:

  • MSDN WM_MOUSEACTIVATE: https ://msdn.microsoft.com/en-us/library/windows/desktop/ms645612( v = vs。85).aspx
  • 如何在WPF中处理WndProc消息: 如何在WPF 中处理WndProc消息?
  • 通知窗口 – 防止窗口获得焦点: 通知窗口 – 防止窗口获得焦点

也许PopupWindow而不是Window会是你想要的? 它有一个Focusable属性,你可以设置为false(默认情况下我认为可能是假的)。