プログラム系統備忘録ブログ

記事中のコードは自己責任の下でご自由にどうぞ。

WPFでのメニューとキーボード操作時のフォーカス移動の話

メニュー関連の次の記事: WPFのメニューとアクセスキーとIME状態

この記事の参考元: WPF menu tab navigation - Stack Overflow

説明

WPFの Menu Class はItemsControlから間接的に派生しており、 MenuItem Class はHeaderedItemsControlから派生しているように、他のコントロール類と親和性の高いクラス階層になっています。
しかしその影響か、プロパティを設定していない状態では、Tabキーやカーソルキーで操作をするとキーボードフォーカスを受け取ってしまいます。

具体例

何の変哲もない、Menuクラスとメインコンテンツ(ここではボタン2つ)を設置したViewが次になります:

<Window x:Class="WpfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        SizeToContent="WidthAndHeight">
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="ファイル(_F)">
                <MenuItem Header="新規作成(_N)" />
                <MenuItem Header="終了(_X)" />
            </MenuItem>
            <MenuItem Header="編集(_E)">
                <MenuItem Header="元に戻す(_U)" />
                <MenuItem Header="やり直す(_R)" />
            </MenuItem>
        </Menu>
        <StackPanel Orientation="Horizontal">
            <Button Content="ボタン1" />
            <Button Content="ボタン2" />
        </StackPanel>
    </DockPanel>
</Window>

メニューについても他のコントロールと同様に、 AccessText Class のExampleにあるようにアンダースコアの次の文字がアクセスキーとして認識されます。
Command Property やイベントハンドラを設定していないのでMenuItemをクリックしても何も起こりませんが、UIの話なのでこのxamlで十分です。

ここから本題、上のxamlでは次の問題があります。

  • 右のボタンにフォーカスがある状態でTabキーを押すと、メニューにフォーカスが移る
  • 右のボタンにフォーカスがある状態でCtrl+Tabを押すと、メニューにフォーカスが移る
  • どちらかのボタンにフォーカスがある状態で上矢印キーを押すと、メニューにフォーカスが移る

WinFormsではこれらの操作を行ってもメニューにフォーカスは移りません。(Ctrl+Tabではボタン間のフォーカス移動すら起こりませんでした。)

解決策

KeyboardNavigation Class の添付プロパティを使用します。

これらを全て設定したMenuは次になります:

<Menu DockPanel.Dock="Top"
      KeyboardNavigation.TabNavigation="None"
      KeyboardNavigation.ControlTabNavigation="None"
      KeyboardNavigation.DirectionalNavigation="None">
    <!-- MenuItemは同じなので省略 -->
</Menu>

このように設定すると、Tabキーを押しても、カーソルキーを押しても、Ctrl+Tabを押しても、メニューにキーボードフォーカスが移動しないことを確認できます。
当然ながら、AltキーやF10を押したり、アクセスキーを押した場合はメニューにフォーカスが移ります。
メニューにフォーカスがある状態では、TabキーやカーソルキーでMenuItem間を移動できます。