簡體   English   中英

禁用 WPF 窗口焦點

[英]Disable WPF Window Focus

我有一個 WPF 窗口,只有當您通過 Visibility.Hidden 和 Visibility.Visible 按住 Tab 鍵時才會顯示。 但是,按住該鍵會將焦點從活動應用程序轉移到 WPF 窗口。 我可以禁用此行為嗎? 更進一步:是否可以完全阻止窗口在單擊控件時獲得焦點,但仍然注冊控件的單擊動作?

在別處找到答案:

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);

    //Set the window style to noactivate.
    var 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 ,這樣標記的表單將不再竊取焦點。

您可以通過添加自定義 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;

參考:

防止在 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();
}

也許你想要一個 PopupWindow 而不是 Window ? 它有一個 Focusable 屬性,您可以將其設置為 false(我認為默認情況下可能為 false)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM