Как установить логический фокус, не давая фокус клавиатуры?

Как я могу в коде определить логический фокус контейнера или сфокусированного дочернего элемента, БЕЗ предоставления ему клавиатуры фокус?

Я просто хочу контролировать, какой дочерний элемент получит фокус, когда элемент управления получит фокус с помощью клавиши Tab или нажатия на часть контейнера, которая не затрагивает дочерний элемент, но не дает ему (или крадет )фактическое фокус, если он еще не имеет его.

И я также хочу, чтобы по-прежнему был возможен выбор конкретного потомка с помощью жеста клавиатуры или щелчка по нему мышью.

Я понимаю разницу в WPF между фокусом клавиатуры и логическим фокусом, а также тот факт, что для элемента наличие фокуса клавиатуры подразумевает наличие логического фокуса, но наличие логического фокуса не означает, что элемент имеет фокус клавиатуры.

Я также понимаю, что присоединенное свойство FocusManager.FocusedElement определяет, какой элемент имеет логический фокус в визуальном дереве, начиная с элемента, определяющего это свойство.

Я понял, что это свойство используется не только тогда, когда FocusManager.IsFocusScope имеет значение true, но также и для таких контейнеров, как GroupBox .

Я предпринял много попыток, провел множество поисков и читал по основной теме WPF,но пока безуспешно, я не понимаю, чего мне не хватает:

  • Вызов FocusManager.SetFocusedElementтакже дает фокус клавиатуры, и если я временно изменяю свойство Focusable моего дочернего элемента на false непосредственно перед этим, это работает только самый первый раз, когда ни у одного ребенка не было фокуса до, но не после того, как ребенок получил фокус
  • Обработка событий GotKeyboardFocus и PreviewGotKeyboardFocus в элементе или контейнере для переопределения первоначально сфокусированного элемента также не работает, поскольку я не могу сказать, был ли фокус получен с помощью мыши или клавиатуры, и был ли фокус установлен непосредственно на дочернем элементе или косвенно через контейнер.
  • Пример, иллюстрирующий то, чего я пытаюсь достичь. :У меня есть простая группа RadioButtons, и я хочу динамически контролировать в коде, какая опция получит фокус, когда пользователь нажимает «Tab», чтобы переместить фокус на эту GroupBox (обычно имеет параметрisChecked=true).

    <GroupBox Header="Options" Name="myGroupBox"
              KeyboardNavigation.TabNavigation="Once" 
              KeyboardNavigation. DirectionalNavigation="Cycle" >
        <StackPanel>
            <RadioButton GroupName="g1" Name="opt1" Content="Option _1"/>
            <RadioButton GroupName="g1" Name="opt2" Content="Option _2"/>
            <RadioButton GroupName="g1" Name="opt3" Content="Option _3"/>
        </StackPanel>
    </GroupBox>
    

    Заключительный комментарий, я знаю, как реализовать динамический список опций, используя ListBox , привязав selectedItem списка к свойству контекста данных, а затем через стили и шаблоны в ListBoxItem связывают свойство IsChecked элемента RadioButton в шаблоне элемента со свойством IsSelected его родителя ListBoxItem , и это работает, но для моего конкретного случая мне нужно, чтобы мои RadioButtons были напрямую привязаны к свойствам моего контекста данных, я не могу одновременно привязать их к свойству IsSelected списка.

    6
    задан M3HD1 4 May 2012 в 20:45
    поделиться