# 機能設計書 56-KeyboardNavigation

## 概要

本ドキュメントは、Avaloniaフレームワークにおけるキーボードナビゲーション（KeyboardNavigation）機能の設計仕様を定義する。KeyboardNavigationは、Tabキーや矢印キーによるフォーカス移動を制御するための添付プロパティを提供する静的クラスである。

### 本機能の処理概要

KeyboardNavigationは、コンテナ要素内でのキーボードによるフォーカス移動パターンを定義する添付プロパティ群を提供する。TabIndex、TabNavigation、IsTabStopなどのプロパティにより、開発者は柔軟にフォーカス移動の動作をカスタマイズできる。

**業務上の目的・背景**：キーボードによるナビゲーションは、アクセシビリティの観点から非常に重要である。マウスを使用できないユーザーや、効率的な操作を求めるパワーユーザーにとって、論理的で予測可能なフォーカス移動は必須の機能である。KeyboardNavigationは、WPFと互換性のあるナビゲーションモデルを提供し、開発者が直感的にフォーカス制御を実装できるようにする。

**機能の利用シーン**：
- フォーム内でのTabキーによるフィールド間移動
- ツールバーでの矢印キーによるボタン間移動
- ダイアログでのTab順序のカスタマイズ
- 特定の要素をタブストップから除外

**主要な処理内容**：
1. TabIndex添付プロパティによるタブ順序の指定
2. TabNavigation添付プロパティによるコンテナ内ナビゲーションモードの設定
3. TabOnceActiveElement添付プロパティによるOnceモードの初期フォーカス指定
4. IsTabStop添付プロパティによるタブストップの有効/無効切り替え

**関連システム・外部連携**：KeyboardNavigationHandler、TabNavigation、XYFocus、FocusManagerと連携してフォーカス移動を実現する。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | Focus | 補助機能 | Tabキーによるフォーカス移動制御 |

## 機能種別

フォーカス管理 / 添付プロパティ / ナビゲーション制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| TabIndex | int | No | タブ順序（デフォルト: int.MaxValue） | 整数値 |
| TabNavigation | KeyboardNavigationMode | No | ナビゲーションモード（デフォルト: Continue） | 有効な列挙値 |
| IsTabStop | bool | No | タブストップ有効（デフォルト: true） | bool値 |
| TabOnceActiveElement | IInputElement? | No | Onceモード時のアクティブ要素 | null許容 |

### 入力データソース

- XAML属性での添付プロパティ設定
- コードビハインドでのプロパティ設定

## 出力仕様

### 出力データ

該当なし（添付プロパティの設定のみ）

### 出力先

該当なし

## 処理フロー

### 処理シーケンス

```
1. Tabキー押下
   └─ KeyboardNavigationHandlerが検出
2. 現在のフォーカス要素取得
   └─ FocusManagerから取得
3. ナビゲーション方向決定
   └─ Shift+TabならPrevious、TabならNext
4. 次のフォーカス要素探索
   └─ TabNavigation/TabIndex/IsTabStopを考慮
5. フォーカス移動
   └─ 見つかった要素にフォーカス設定
```

### フローチャート

```mermaid
flowchart TD
    A[Tabキー押下] --> B{Shift押下?}
    B -->|Yes| C[NavigationDirection.Previous]
    B -->|No| D[NavigationDirection.Next]
    C --> E[GetPrevTab呼び出し]
    D --> F[GetNextTab呼び出し]
    E --> G{TabNavigation確認}
    F --> G
    G -->|Continue| H[現在コンテナを超えて探索]
    G -->|Cycle| I[コンテナ内でサイクル]
    G -->|Once| J[TabOnceActiveElementへ]
    G -->|Contained| K[コンテナ内のみ探索]
    G -->|Local| L[ローカルタブインデックスのみ]
    G -->|None| M[ナビゲーションなし]
    H --> N[次の要素にフォーカス]
    I --> N
    J --> N
    K --> N
    L --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-56-01 | TabIndex順序 | 小さい値が先にフォーカスを受ける | 複数要素間でのタブ移動時 |
| BR-56-02 | IsTabStop判定 | falseの要素はタブストップをスキップ | Tab移動時 |
| BR-56-03 | Continue継続 | 親コンテナを超えて探索を継続 | TabNavigation.Continue |
| BR-56-04 | Cycleサイクル | コンテナの最後から最初へ戻る | TabNavigation.Cycle |
| BR-56-05 | Onceアクティブ | TabOnceActiveElementにのみフォーカス | TabNavigation.Once |
| BR-56-06 | Contained制限 | コンテナ内のみでナビゲーション | TabNavigation.Contained |

### 計算ロジック

**タブ順序決定**：
1. IsTabStop=falseの要素を除外
2. TabIndexでソート（昇順）
3. 同じTabIndex内ではビジュアルツリー順

## データベース操作仕様

### 操作別データベース影響一覧

該当なし（UIフレームワークのためデータベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | なし | - | - |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- フォーカス探索はビジュアルツリー探索を伴うが、即座に完了する必要がある

## セキュリティ考慮事項

特になし

## 備考

- KeyboardNavigationMode列挙型はWPFと互換
- XYFocusとの連携で矢印キーナビゲーションも実現

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

キーボードナビゲーションで使用される型定義を先に把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | KeyboardNavigationMode.cs | `src/Avalonia.Base/Input/KeyboardNavigationMode.cs` | Continue/Cycle/Once/Contained/Local/None列挙型 |
| 1-2 | KeyboardNavigation.cs | `src/Avalonia.Base/Input/KeyboardNavigation.cs` | 添付プロパティ定義 |

**読解のコツ**: KeyboardNavigationModeの各値の意味を理解することが重要。Continueは親を超えて継続、Cycleは循環、Onceは一度だけアクティブ要素へ、Containedはコンテナ内限定、Localはローカルタブインデックスのみ、Noneはナビゲーション無効。

#### Step 2: 添付プロパティを理解する

4つの添付プロパティの定義と用途を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | KeyboardNavigation.cs | `src/Avalonia.Base/Input/KeyboardNavigation.cs` | TabIndex/TabNavigation/IsTabStop/TabOnceActiveElementプロパティ |

**主要処理フロー**:
1. **11-15行目**: TabIndexProperty定義（デフォルトint.MaxValue）
2. **24-27行目**: TabNavigationProperty定義
3. **37-40行目**: TabOnceActiveElementProperty定義
4. **48-52行目**: IsTabStopProperty定義（デフォルトtrue）

#### Step 3: ナビゲーションハンドラーを理解する

実際のフォーカス移動処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | KeyboardNavigationHandler.cs | `src/Avalonia.Base/Input/KeyboardNavigationHandler.cs` | Tab/矢印キー処理 |

**主要処理フロー**:
- **36-37行目**: SetOwnerでKeyDownEventハンドラー登録
- **48-54行目**: GetNextメソッドで次のフォーカス要素取得
- **101-118行目**: Moveメソッドでフォーカス移動実行
- **125-147行目**: OnKeyDownでTab/矢印キー処理

#### Step 4: タブナビゲーション実装を理解する

TabNavigationクラスのアルゴリズムを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TabNavigation.cs | `src/Avalonia.Base/Input/Navigation/TabNavigation.cs` | GetNextTab/GetPrevTabメソッド |

### プログラム呼び出し階層図

```
KeyboardNavigationHandler.OnKeyDown
    │
    ├─ Key == Tab
    │      │
    │      └─ Move(current, Next/Previous, keyModifiers)
    │             │
    │             └─ GetNextPrivate
    │                    │
    │                    ├─ TabNavigation.GetNextTab
    │                    │      └─ TabIndex/IsTabStop考慮
    │                    │
    │                    └─ TabNavigation.GetPrevTab
    │                           └─ 逆順探索
    │
    └─ Key == Left/Right/Up/Down
           │
           └─ Move(current, Left/Right/Up/Down, keyModifiers)
                  │
                  └─ XYFocus.TryDirectionalFocus
                         └─ 方向ベースの探索
```

### データフロー図

```
[入力]                     [処理]                        [出力]

Tabキー押下 ───▶ KeyboardNavigationHandler ───▶ Focus移動
                      │
                      ├─ 現在要素取得
                      ├─ TabNavigation確認
                      ├─ TabIndex/IsTabStop確認
                      └─ 次要素探索

矢印キー押下 ───▶ KeyboardNavigationHandler ───▶ Focus移動
                      │
                      └─ XYFocus.TryDirectionalFocus
                             └─ 方向ベース探索
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| KeyboardNavigation.cs | `src/Avalonia.Base/Input/KeyboardNavigation.cs` | ソース | 添付プロパティ定義 |
| KeyboardNavigationMode.cs | `src/Avalonia.Base/Input/KeyboardNavigationMode.cs` | ソース | ナビゲーションモード列挙型 |
| KeyboardNavigationHandler.cs | `src/Avalonia.Base/Input/KeyboardNavigationHandler.cs` | ソース | キー押下ハンドラー |
| IKeyboardNavigationHandler.cs | `src/Avalonia.Base/Input/IKeyboardNavigationHandler.cs` | ソース | インターフェース定義 |
| TabNavigation.cs | `src/Avalonia.Base/Input/Navigation/TabNavigation.cs` | ソース | タブナビゲーション実装 |
| XYFocus.Impl.cs | `src/Avalonia.Base/Input/Navigation/XYFocus.Impl.cs` | ソース | 方向ナビゲーション実装 |
| ICustomKeyboardNavigation.cs | `src/Avalonia.Base/Input/ICustomKeyboardNavigation.cs` | ソース | カスタムナビゲーション |
| FocusManager.cs | `src/Avalonia.Base/Input/FocusManager.cs` | ソース | フォーカス管理 |
