# 機能設計書 5-Control

## 概要

本ドキュメントは、Avaloniaフレームワークにおけるすべてのコントロールの基底クラスである`Control`の機能設計を記述する。`InputElement`を継承し、タグ、コンテキストメニュー、フォーカスアドーナー、ライフサイクルイベント（Loaded/Unloaded）などの機能を提供する。

### 本機能の処理概要

`Control`クラスは、Avaloniaコントロールの基底クラスとして以下の機能を提供する：
- **Tagプロパティ**：ユーザー定義データの添付
- **コンテキストメニュー**：右クリックメニューとContextFlyoutの管理
- **フォーカスアドーナー**：キーボードナビゲーション時のフォーカス表示
- **Loaded/Unloadedイベント**：コントロールのライフサイクル管理
- **SizeChangedイベント**：サイズ変更通知
- **データテンプレート**：IDataTemplateHost実装

**業務上の目的・背景**：UIコントロールには共通して必要な機能（コンテキストメニュー、タグデータ、ライフサイクル通知など）がある。`Control`クラスはこれらを一元的に提供し、すべての具象コントロールの基盤となる。

**機能の利用シーン**：
- コンテキストメニューの設定と表示
- カスタムデータのコントロールへの添付（Tag）
- コントロールの初期化完了タイミングでの処理（Loaded）
- フォーカス表示のカスタマイズ

**主要な処理内容**：
1. `Tag`プロパティによるユーザーデータ添付
2. `ContextMenu`/`ContextFlyout`によるコンテキストメニュー管理
3. `FocusAdorner`によるフォーカス表示カスタマイズ
4. `Loaded`/`Unloaded`イベントによるライフサイクル通知
5. `SizeChanged`イベントによるサイズ変更通知
6. `DataTemplates`コレクションによるローカルテンプレート管理

**関連システム・外部連携**：
- `InputElement`：入力処理基盤
- `AdornerLayer`：フォーカスアドーナーの表示
- `ContextMenu`/`FlyoutBase`：コンテキストメニュー
- `Dispatcher.UIThread`：Loadedイベントの遅延発火

**権限による制御**：特になし（フレームワーク基盤クラス）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は全コントロールの基盤であり、特定の画面に紐づかない |

## 機能種別

フレームワーク基盤 / コントロール基底 / ライフサイクル管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| FocusAdorner | ITemplate<Control>? | No | フォーカス時のアドーナーテンプレート | - |
| Tag | object? | No | ユーザー定義データ | - |
| ContextMenu | ContextMenu? | No | コンテキストメニュー | - |
| ContextFlyout | FlyoutBase? | No | コンテキストフライアウト | - |

### 入力データソース

- XAMLまたはコードからのプロパティ設定
- ポインターイベント（右クリック）からのコンテキストメニュー要求
- キーボードイベント（ContextMenuキー）からのコンテキストメニュー要求
- ビジュアルツリーのアタッチ/デタッチ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ContextRequested | event | コンテキストメニュー要求イベント |
| Loaded | event | コントロール初期化完了イベント |
| Unloaded | event | コントロール破棄イベント |
| SizeChanged | event | サイズ変更イベント |
| IsLoaded | bool | 読み込み完了フラグ |

### 出力先

- イベントリスナー
- アドーナーレイヤー（フォーカスアドーナー）

## 処理フロー

### 処理シーケンス

```
1. ビジュアルツリーにアタッチ
   └─ OnAttachedToVisualTreeCore
   └─ InitializeIfNeeded
   └─ ScheduleOnLoadedCore（Loadedイベントをスケジュール）

2. Loadedイベント発火（遅延）
   └─ Dispatcher.UIThread.Post(DispatcherPriority.Loaded)
   └─ _loadedProcessingQueue処理
   └─ OnLoadedCore
   └─ OnLoaded（仮想メソッド）
   └─ Loadedイベント発火

3. コンテキストメニュー要求
   └─ OnPointerReleased（右クリック）
   └─ または OnKeyUp（ContextMenuキー）
   └─ または OnHolding（長押し）
   └─ ContextRequestedEventArgs作成
   └─ RaiseEvent

4. フォーカス取得
   └─ OnGotFocus
   └─ Tab/Directionalナビゲーションの場合
   └─ FocusAdornerテンプレートから生成
   └─ AdornerLayerに追加

5. ビジュアルツリーからデタッチ
   └─ OnDetachedFromVisualTreeCore
   └─ OnUnloadedCore
   └─ Unloadedイベント発火
```

### フローチャート

```mermaid
flowchart TD
    A[Control作成] --> B[ビジュアルツリーにアタッチ]
    B --> C[ScheduleOnLoadedCore]
    C --> D[_loadedQueueに追加]
    D --> E{初回?}
    E -->|Yes| F[Dispatcher.Post]
    E -->|No| G[待機]
    F --> H[loadedProcessingAction]
    H --> I[OnLoadedCore]
    I --> J{IsAttachedToLogicalTree?}
    J -->|Yes| K[_loadState = Loaded]
    J -->|No| L[_loadState = Unloaded]
    K --> M[OnLoaded]
    M --> N[Loadedイベント発火]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Loaded遅延発火 | LoadedイベントはDispatcherPriority.Loadedで遅延発火 | ビジュアルツリーアタッチ時 |
| BR-02 | フォーカスアドーナー条件 | Tab/Directionalナビゲーションでフォーカス時のみ表示 | OnGotFocus |
| BR-03 | コンテキストメニュー要求 | 右クリック、ContextMenuキー、長押しで発火 | 各イベント時 |
| BR-04 | SizeChanged条件 | Boundsの位置変更では発火せず、サイズ変更時のみ | OnPropertyChanged |
| BR-05 | LoadState管理 | Unloaded→LoadPending→Loadedの状態遷移 | ライフサイクル |
| BR-06 | SetterValue制限 | ControlをSetterの値として直接使用不可（Templateでラップ必要） | ISetterValue |

### 計算ロジック

**SizeChanged判定**：
```csharp
if (newValue.Size != oldValue.Size)
{
    // SizeChangedイベント発火
}
// 位置のみ変更の場合は発火しない
```

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

該当なし（メモリ内データ構造のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidOperationException | ControlをSetterの値として直接使用 | `<Template>`でラップ |

### リトライ仕様

該当なし

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

該当なし（メモリ内操作のみ）

## パフォーマンス要件

- Loadedイベントはバッチ処理（`_loadedQueue`/`_loadedProcessingQueue`の分離）
- Loadedコールバック内で新規コントロール追加しても例外を回避
- フォーカスアドーナーは遅延生成

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

- 特別なセキュリティ考慮事項なし（フレームワーク内部クラス）

## 備考

- WPFの`Control`+`FrameworkElement`の一部機能に相当
- Loadedイベントの発火タイミングはWPFと同様

---

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

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

### 推奨読解順序

#### Step 1: クラス定義とプロパティを理解する

基本的なプロパティ定義を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Control.cs | `src/Avalonia.Controls/Control.cs` | 19-28行目：クラス定義とXMLコメント |
| 1-2 | Control.cs | `src/Avalonia.Controls/Control.cs` | 30-91行目：プロパティ・イベント定義 |

**読解のコツ**:
- `InputElement`を継承していることを確認
- `IDataTemplateHost`、`IVisualBrushInitialize`、`ISetterValue`インターフェース実装

#### Step 2: ライフサイクル管理を理解する

Loaded/Unloadedイベントの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Control.cs | `src/Avalonia.Controls/Control.cs` | 94-106行目：静的フィールド（_loadedQueue等） |
| 2-2 | Control.cs | `src/Avalonia.Controls/Control.cs` | 261-289行目：loadedProcessingAction |
| 2-3 | Control.cs | `src/Avalonia.Controls/Control.cs` | 295-309行目：ScheduleOnLoadedCore |
| 2-4 | Control.cs | `src/Avalonia.Controls/Control.cs` | 315-329行目：OnLoadedCore |
| 2-5 | Control.cs | `src/Avalonia.Controls/Control.cs` | 335-353行目：OnUnloadedCore |

**主要処理フロー**:
- **261-289行目**: `loadedProcessingAction`でキューを処理、再帰的な追加に対応
- **295-309行目**: `ScheduleOnLoadedCore`で初回のみDispatcher.Post
- **315-329行目**: `OnLoadedCore`で状態確認後にOnLoaded呼び出し
- **583-588行目**: `LoadState`列挙型の定義

#### Step 3: コンテキストメニューを理解する

コンテキストメニュー要求の仕組みを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Control.cs | `src/Avalonia.Controls/Control.cs` | 490-502行目：OnPointerReleased（右クリック） |
| 3-2 | Control.cs | `src/Avalonia.Controls/Control.cs` | 505-539行目：OnKeyUp（ContextMenuキー） |
| 3-3 | Control.cs | `src/Avalonia.Controls/Control.cs` | 392-404行目：OnHolding（長押し） |

**主要処理フロー**:
- **490-502行目**: 右クリック時に`ContextRequestedEventArgs`を作成してRaiseEvent
- **505-539行目**: ホットキー設定からContextMenuキーを取得して照合
- **392-404行目**: タッチ長押し時のコンテキスト要求

#### Step 4: フォーカスアドーナーを理解する

フォーカス表示の仕組みを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Control.cs | `src/Avalonia.Controls/Control.cs` | 415-446行目：OnGotFocus |
| 4-2 | Control.cs | `src/Avalonia.Controls/Control.cs` | 448-459行目：OnLostFocus |
| 4-3 | Control.cs | `src/Avalonia.Controls/Control.cs` | 259行目：GetTemplateFocusTarget |

**主要処理フロー**:
- **415-446行目**: Tab/Directionalナビゲーション時にFocusAdornerを生成・表示
- **448-459行目**: フォーカス喪失時にアドーナーを削除

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

```
Control
    │
    ├─ InputElement（入力処理）
    │      └─ Layoutable → Visual → StyledElement
    │
    ├─ ライフサイクル管理
    │      ├─ ScheduleOnLoadedCore
    │      ├─ OnLoadedCore / OnUnloadedCore
    │      └─ Dispatcher.UIThread
    │
    ├─ コンテキストメニュー
    │      ├─ ContextMenu
    │      ├─ ContextFlyout
    │      └─ ContextRequestedEvent
    │
    ├─ フォーカスアドーナー
    │      ├─ FocusAdorner（テンプレート）
    │      └─ AdornerLayer
    │
    └─ データテンプレート
           └─ DataTemplates（IDataTemplateHost）
```

### データフロー図

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

OnAttachedToVisualTreeCore
        │
        ▼
   ScheduleOnLoadedCore
        │
        ▼
   _loadedQueue.Add(this)
        │
        ▼
   Dispatcher.Post(Loaded) ─────────▶ 遅延実行
                                          │
                                          ▼
                                    loadedProcessingAction
                                          │
                                          ▼
                                    OnLoadedCore
                                          │
                                          ▼
                                    OnLoaded ──────▶ Loadedイベント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Control.cs | `src/Avalonia.Controls/Control.cs` | ソース | コントロール基底クラス |
| InputElement.cs | `src/Avalonia.Controls/Primitives/InputElement.cs` | ソース | 入力処理基盤（親クラス） |
| ContextMenu.cs | `src/Avalonia.Controls/ContextMenu.cs` | ソース | コンテキストメニュー |
| FlyoutBase.cs | `src/Avalonia.Controls/Flyouts/FlyoutBase.cs` | ソース | フライアウト基底 |
| AdornerLayer.cs | `src/Avalonia.Controls/Primitives/AdornerLayer.cs` | ソース | アドーナーレイヤー |
| DataTemplates.cs | `src/Avalonia.Controls/DataTemplates.cs` | ソース | データテンプレートコレクション |
| IDataTemplateHost.cs | `src/Avalonia.Controls/Templates/IDataTemplateHost.cs` | ソース | データテンプレートホストIF |
