Отключить фокус окна WPF

У меня есть окно WPF, которое появляется только тогда, когда вы удерживаете клавишу табуляции с помощью Visibility.Hidden и Visibility.Visible. Однако удерживание клавиши сдвигает фокус с активного приложения на окно WPF. Могу ли я отключить это поведение? Идем еще дальше: возможно ли полностью предотвратить попадание фокуса, даже когда элемент управления нажат, но все еще регистрирует действие щелчка элемента управления?

Ответ 1

Нашел ответ в другом месте:

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

Ответ 2

Поскольку формы WPF.NET 3.5 SP1 имеют свойство ShowActivated. Установите это значение в false и форма, отмеченная таким образом, больше не будет крать фокус.

Ответ 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();
}

Ответ 4

Вы можете запретить активации WPF Window при щелчке мыши, добавив пользовательский WndProc и обработчик WM_MOUSEACTIVATE:

    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;

Рекомендации:

Ответ 5

Может быть, PopupWindow вместо Window будет тем, что вы хотите? Он имеет свойство Focusable, которое вы можете установить в false (по-моему, по умолчанию это может быть неверно).