禁用WPF窗口焦点

时间:2012-09-25 22:15:51

标签: c# wpf focus

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

5 个答案:

答案 0 :(得分:18)

在别处找到答案:

    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);

答案 1 :(得分:10)

  

由于.NET 3.5 SP1 WPF表单具有ShowActivated属性。设置这个   至false,如此标记的形式不会再没有重点。

答案 2 :(得分:3)

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

答案 3 :(得分:3)

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

参考文献:

答案 4 :(得分:0)

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