У меня есть окно WPF, которое появляется только тогда, когда вы удерживаете клавишу табуляции с помощью Visibility.Hidden и Visibility.Visible. Однако удерживание клавиши сдвигает фокус с активного приложения на окно WPF. Могу ли я отключить это поведение? Идем еще дальше: возможно ли полностью предотвратить попадание фокуса, даже когда элемент управления нажат, но все еще регистрирует действие щелчка элемента управления?
Отключить фокус окна 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;
Рекомендации:
- MSDN WM_MOUSEACTIVATE: https://msdn.microsoft.com/en-us/library/windows/desktop/ms645612(v=vs.85).aspx
- Как обрабатывать сообщения WndProc в WPF: как обрабатывать сообщения WndProc в WPF?
- Окно уведомлений. Предотвращение фокуса окна. Окно уведомлений. Предотвращение фокуса окна.
Ответ 5
Может быть, PopupWindow вместо Window будет тем, что вы хотите? Он имеет свойство Focusable, которое вы можете установить в false (по-моему, по умолчанию это может быть неверно).