如何像在关闭事件中一样从WPF窗口中移除焦点?

4

我希望从我的WPF窗口中移除焦点,并将焦点重新设置到上一个“Windows窗口”,就像关闭普通WPF窗口时发生的那样。

我的WPF窗口在普通的“Windows窗口”上工作。我不想每次单击“层WPF窗口”上的某些东西时失去焦点。

我的解决方法是,在Button_Click事件方法中将焦点设置回上一个“Windows窗口”。

希望您能帮助我,因为我在互联网上没有找到关于这个不常见问题的任何信息。


2
这是由操作系统而非WPF处理的。我认为你只有关闭窗口或诉诸于WinAPI才能做到这一点。 - Federico Berasategui
我添加了更多的信息。也许有一个解决办法可以解决我的问题。 - AntiStoopMode
2个回答

2

您需要使用P/Invoke技术,从WinAPI中获取以下函数:

[DllImport("user32.dll")]
static extern IntPtr GetWindow(IntPtr hWnd, uint wCmd);
const uint GW_HWNDNEXT = 2;

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);

如何使用它们:
private void Button_Click(object sender, RoutedEventArgs e)
{
    // Get the WPF window handle
    IntPtr hWnd = new WindowInteropHelper(Application.Current.MainWindow).Handle;

    // Look for next visible window in Z order
    IntPtr hNext = hWnd;
    do
        hNext = GetWindow(hNext, GW_HWNDNEXT);
    while (!IsWindowVisible(hNext));

    // Bring the window to foreground
    SetForegroundWindow(hNext);
}

我认为你那里有一个打字错误。我认为你想要 hNext = GetWindow(hNext, GW_HWNDNEXT); - CodingGorilla
@Joulukuusi,它运行良好并帮助了我很多。问题是当我的WPF窗口设置为TopMost(因为我想将其用作层)时,它无法工作。我尝试了SwitchToThisWindow(IntPtr hWnd, bool fAltTab)方法,但遇到了同样的问题。只有在我的窗口不是TopMost时才能正常工作。 - AntiStoopMode
@AntiStoopMode,你不应该使用SwitchToThisWindow,因为“此函数不适用于一般用途。它可能会在以后的Windows版本中更改或不可用”(引自http://msdn.microsoft.com/en-us/library/windows/desktop/ms633553.aspx)。一个可能的解决方法是在`Button_Click`的开始处设置`TopMost = false,并在Window.GotFocus事件中将其恢复为true`。 - skink
@Joulukuusi 非常感谢!通过设置 TopMost = false 并稍后再次激活它,它可以按照我想要的方式工作。 - AntiStoopMode

1
你可以将窗口最小化,这样就会将焦点放在“最后一个窗口”的窗口上。
window.WindowState = System.Windows.WindowState.Minimized;

谢谢您的回答,但我只想将焦点返回并保持窗口打开。 - AntiStoopMode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接