WPFでフォーカス遷移を行ううえで抑えて起きたい3つのポイントについてご紹介します。
TabIndex
コントロールにTabIndexを付与すると、その順番にフォーカス遷移します。
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Width="200">テキストボックス(TabIndex:1)</TextBlock>
<TextBox x:Name="textBox" Width="200" Text="{Binding TextBoxVal()
ue}" TabIndex="1">
</TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Width="200">カスタムコントロール(TabIndex:3)</TextBlock>
<customcontrols:SeachTextBox Width="200" TabIndex="3"></customcontrols:SeachTextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Width="200">デートピッカー(TabIndex:2)</TextBlock>
<DatePicker Width="200" x:Name="datePicker" SelectedDate="{Binding DatePickerData}" TabIndex="2"/>
</StackPanel>
物理フォーカス、論理フォーカス
物理フォーカスは別名、キーボードフォーカスとも呼ばれています。
例えば、Application Aのテキストボックスにフォーカスが設定された状態で、キーボードで入力するとApplication Aのテキストボックスに入力できます。この時、Application Aのテキストボックスは物理フォーカスを取得している状態です。
そこから、Application Bを選択すると、Application Bがアクティブになり、Application Aは非アクティブ、Application Aのテキストボックスへのキーボード入力は出来なくなります。この状態は、Application Aのテキストボックスは物理フォーカスが失われた状態となります。ただし、Application Aが再度アクティブになった際に、Application Aのテキストボックスが物理フォーカスを取得します。これは、Application A内部でテキストボックスが論理フォーカスを取得しているためです。
- Application Aを選択し、テキストボックスにフォーカスを設定。
ー> Application Aのテキストボックスは、物理フォーカスを取得済、論理フォーカスを取得済 - Application B を選択。
ー> Application Aのテキストボックスは、物理フォーカスは取得していないが、論理フォーカスを引き続き保持。 - Application A を選択。
ー> Application Aのテキストボックスは、論理フォーカスを取得していたため、Application A がアクティブになった時点で物理フォーカスも再取得。
KeyboardNavigation
これらは、ひとつのコントロール配下にあるフォーカス遷移の方向性を決定します。
フィールド | 概要 |
---|---|
Contained | コンテナーの末尾または先頭に達したとき、ナビゲーションの方向に応じて最初または最後の項目にフォーカスが戻りますが、コンテナーの先頭または末尾を越えて移動することはありません。 |
Continue | ナビゲーション ストップである各要素が、キーボード フォーカスを受け取ります。 端に達すると、ナビゲーションはそれが含まれている要素から離れます。 |
Cycle | コンテナーの末尾または先頭に達したとき、ナビゲーションの方向に応じて最初または最後の項目にフォーカスが戻ります。 フォーカスは、論理ナビゲーションを使用してコンテナーから離れることはできません。 |
Local | タブ インデックスは、このコンテナー内のみのローカル サブツリーで考慮され、その後は Continue と同様に機能します。 |
None | このコンテナー内では、キーボード ナビゲーションが許可されていません。 |
Once | コンテナーおよびその子要素全体で 1 度だけフォーカスを受け取ります。 ツリーの最初の子か、グループ内で最後にフォーカスがあった要素が、フォーカスを受け取ります。 |
利用頻度としては、Cycleが一番多いですね。Continueはたとえば、DataGrid内の最後の行、列までフォーカス遷移した際に、DataGridの次のコントロールへ遷移する動作となります。もし、DataGrid内部でフォーカス遷移をくるくる回したい場合は、Cycleを指定すれば実現できます。