Wpf keyboard focus: loss of focus after opening a menu?

It seems very easy, but it definitely does not work as expected. In WPF 4.0, I am trying to create a window with a menu bar that accepts keyboard shortcuts ... A simple window, the menu bar at the top and some other things (inside AvalonDock , which may be part of the problem).

There's one catch: the menu bar and contents are in another user control (let’s call it SadPanda because it makes me sad panda), which is the direct contents of the window. The logical hierarchy looks something like this (not real XAML):

 <Window> <UserControl x:Name="SadPanda" Focusable="True" FocusManager.IsFocusScope="True"> <Grid> <MenuBar/> <AvalonDock:DockingManager> <PandaFood> </AvalonDock:DockingManager> </Grid> </UserControl> </Window> 

The contents of the window require access to the Handle window, so it is installed after the window is loaded as follows:

 window.Loaded += delegate { window.Content = new SadPanda(); }; 

The menu bar and shortcuts have routed commands tied to SadPanda, and when the keyboard focus is lost, input gestures no longer work, which means a sad panda. I added:

 LostKeyboardFocus += (sender, e) => Debug.WriteLine("Lost focus to " + e.NewFocus); GotKeyboardFocus += (sender, e) => Debug.WriteLine("Got focus from " + e.OldFocus); 

... and it seems that the focus is returning to the window, not to SadPanda itself. If I set Focusable = "False" in the window, then the focus will be zero; control is not even considered. I tried (suggested alpha mouse in comments):

 window.GotKeyboardFocus += delegate { Keyboard.Focus(sadPanda); }; 

Even this does not work - it prevents the opening of the menu (they instantly open for a second, then disappear) or text fields that ever get focus ... Do not know why; this seems like the perfect solution.

Basically, I want the user control to have the focus of the top-level keyboard, not the window. What is the easiest way to achieve this?

+4
source share
2 answers

I'm still not sure why this works, but here is the solution I found:

  • Set Focusable="False" and FocusManager.IsFocusScope="False" in the window .
  • Set Focusable="True" and FocusManager.IsFocusScope="True" in the control.

Three. Use the following:

 PleasedPanda.LostKeyboardFocus += (sender, e) => { if(e.NewFocus == null) { Keyboard.Focus(PleasedPanda); } } 

I'm not sure why this works, while the more obvious window.GotKeyboardFocus not, but this WPF is for you.

+3
source

To the right of the hack. You can handle Window.GotKeyboardFocus to immediately focus SadPanda . But there may be better solutions.

+1
source

Source: https://habr.com/ru/post/1332197/


All Articles