Фокус клавиатуры wpf: потерять фокус после открытия меню? - PullRequest
4 голосов
/ 15 декабря 2010

Это кажется действительно простым, но оно определенно не работает, как ожидалось.В WPF 4.0 я пытаюсь создать окно со строкой меню, которая принимает сочетания клавиш ... Просто простое окно, строка меню вверху и некоторые другие вещи (внутри AvalonDock , которыеможет быть частью проблемы).

Есть одна загвоздка: строка меню и контент находятся в другом пользовательском элементе управления (назовем это SadPanda, потому что это делает меня грустной пандой), который является прямым содержаниемокно.Логическая иерархия выглядит примерно так (не фактический XAML):

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

Содержимое окна требует доступа к дескриптору окна, поэтому оно устанавливается после того, как окно загружается следующим образом:

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

В строке меню и ярлыках есть перенаправленные команды , которые привязаны к SadPanda, и когда фокус клавиатуры потерян, жесты ввода больше не работают, отсюда и печальная панда.Я добавил это:

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

... и кажется, что фокус возвращается к окну, а не к самой SadPanda.Если я установлю Focusable = "False" в окне, то фокус исчезнет;контроль никогда даже не рассматривается.Я попытался (предложено альфа-мышью в комментариях):

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

Даже это не работает - это предотвращает открытие меню (они вспыхивают на секунду, а затем исчезают) или текстовые поля когда-либополучить фокус ... Не знаю почему;это кажется идеальным решением.

По сути, я хочу, чтобы пользовательский элемент управления имел фокус клавиатуры верхнего уровня, а не окно.Какой самый простой способ добиться этого?

Ответы [ 2 ]

3 голосов
/ 18 декабря 2010

Я все еще не уверен, почему это работает, но вот решение, которое я нашел:

  1. Установите Focusable="False" и FocusManager.IsFocusScope="False" в окне .
  2. Установите Focusable="True" и FocusManager.IsFocusScope="True" на элементе управления.

Три.Используйте следующее:

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

Я не уверен, почему это работает, в то время как более очевидное window.GotKeyboardFocus нет, но это WPF для вас.

1 голос
/ 15 декабря 2010

Справа от взлома.Вы можете обработать Window.GotKeyboardFocus для немедленной фокусировки SadPanda.Но может быть, есть более хорошие решения.

...