メニュー関連の次の記事: 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 の添付プロパティを使用します。
- Tabキーを押した時の動作は TabNavigation Attached Property で制御できます
- Ctrl+Tabを押した時の動作は ControlTabNavigation Attached Property で制御できます
- カーソルキーを押した時の動作は DirectionalNavigation Attached Property で制御できます
これらを全て設定したMenuは次になります:
<Menu DockPanel.Dock="Top" KeyboardNavigation.TabNavigation="None" KeyboardNavigation.ControlTabNavigation="None" KeyboardNavigation.DirectionalNavigation="None"> <!-- MenuItemは同じなので省略 --> </Menu>
このように設定すると、Tabキーを押しても、カーソルキーを押しても、Ctrl+Tabを押しても、メニューにキーボードフォーカスが移動しないことを確認できます。
当然ながら、AltキーやF10を押したり、アクセスキーを押した場合はメニューにフォーカスが移ります。
メニューにフォーカスがある状態では、TabキーやカーソルキーでMenuItem間を移動できます。