# 機能設計書 19-ContextMenu

## 概要

本ドキュメントは、Avalonia UIフレームワークにおけるContextMenuコントロールの機能設計を記述する。ContextMenuは右クリック時に表示されるコンテキストメニューを提供するコントロールである。

### 本機能の処理概要

ContextMenuは、コントロール上で右クリック（またはコンテキストメニューキー）を行った際に表示されるポップアップメニューである。対象コントロールに関連する操作をメニュー形式で提供する。

**業務上の目的・背景**：デスクトップアプリケーションでは、選択したオブジェクトに対する操作（コピー、ペースト、削除等）を右クリックメニューから提供することが標準的なUXである。ContextMenuはこのパターンを実装し、文脈に応じた操作をユーザーに提供する。

**機能の利用シーン**：
- テキストエディタでのコピー・ペースト・カット
- ファイルリストでの操作メニュー
- グラフィックエディタでのオブジェクト操作
- カスタムコントロール上での操作メニュー

**主要な処理内容**：
1. 右クリック/コンテキストメニューキーによる表示
2. Popup内でのメニュー表示
3. 配置位置の自動調整
4. ライトディスミス（外部クリックで閉じる）
5. メニュー項目の選択とコマンド実行

**関連システム・外部連携**：MenuBaseを継承し、Popupを使用してメニューを表示。Control.ContextMenuプロパティによってコントロールに関連付けられる。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | ContextMenu | 主画面 | ContextMenuコントロールのデモ |
| 97 | ContextMenu | テスト画面 | ContextMenuのテスト |

## 機能種別

ナビゲーションコントロール / コンテキストメニュー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| HorizontalOffset | double | No | 水平オフセット | - |
| VerticalOffset | double | No | 垂直オフセット | - |
| Placement | PlacementMode | No | 配置モード | デフォルト: Pointer |
| PlacementAnchor | PopupAnchor | No | 配置アンカー | - |
| PlacementGravity | PopupGravity | No | 配置重力 | - |
| PlacementRect | Rect? | No | 配置矩形 | - |
| PlacementTarget | Control | No | 配置対象コントロール | - |
| PlacementConstraintAdjustment | PopupPositionerConstraintAdjustment | No | 配置制約調整 | - |
| WindowManagerAddShadowHint | bool | No | ウィンドウマネージャーシャドウヒント | - |
| CustomPopupPlacementCallback | CustomPopupPlacementCallback | No | カスタム配置コールバック | - |

### 入力データソース

- ItemsSourceプロパティへのデータバインディング
- XAMLでのMenuItem直接定義
- Control.ContextMenuプロパティへの設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| IsOpen | bool | メニューの開閉状態 |

### 出力先

- Openedイベント：メニュー開き時
- Closedイベント：メニュー閉じ時
- Openingイベント：メニュー開く前（キャンセル可能）
- Closingイベント：メニュー閉じる前（キャンセル可能）

## 処理フロー

### 処理シーケンス

```
1. コンテキストメニュートリガー
   └─ 右クリック/コンテキストメニューキー
2. ContextRequested イベント
   └─ Control.ContextMenuプロパティからContextMenu取得
3. Opening イベント確認
   └─ キャンセルされなければ続行
4. Open()メソッド呼び出し
   └─ Popup作成・表示
5. メニュー操作
   └─ MenuItem選択/サブメニュー展開
6. Closing イベント確認
   └─ キャンセルされなければClose()実行
7. Close()メソッド呼び出し
   └─ Popup非表示
```

### フローチャート

```mermaid
flowchart TD
    A[右クリック/コンテキストキー] --> B[ContextRequestedイベント]
    B --> C{ContextMenuあり?}
    C -->|No| D[終了]
    C -->|Yes| E[Opening確認]
    E --> F{キャンセル?}
    F -->|Yes| D
    F -->|No| G[Open]
    G --> H[Popup表示]
    H --> I[メニュー操作]
    I --> J{項目選択?}
    J -->|Yes| K[コマンド実行]
    J -->|外部クリック| L[Closing確認]
    K --> L
    L --> M{キャンセル?}
    M -->|Yes| N[メニュー維持]
    M -->|No| O[Close]
    O --> P[Closedイベント]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ライトディスミス | 外部クリックでメニューを閉じる | 常時 |
| BR-02 | 配置モードデフォルト | PlacementMode.Pointerがデフォルト（マウス位置に表示） | Placement未設定時 |
| BR-03 | キーボード表示時の配置 | コンテキストメニューキーで開いた場合はPlacementMode.Bottom | キーボード操作時 |
| BR-04 | フォーカス管理 | 開く前のフォーカス要素を保存し、閉じた後に復元 | 常時 |
| BR-05 | 添付プロパティ制約 | Setterで使用する場合、ContextMenuプロパティのみ許可 | Setter使用時 |

### 計算ロジック

特になし

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

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

該当なし（UIコントロール）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentNullException | 引数エラー | 未接続時にnull引数でOpen() | 接続されたコントロールを指定 |
| ArgumentException | 引数エラー | 接続されていないコントロールでOpen() | 接続されたコントロールを指定 |
| InvalidOperationException | 操作エラー | SetterでContextMenuプロパティ以外に設定 | ContextMenuプロパティのみに設定 |

### リトライ仕様

該当なし

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

該当なし（UIコントロール）

## パフォーマンス要件

特になし

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

特になし（UIコントロールとして汎用的に使用可能）

## 備考

- ISetterValueを実装し、Setterでの使用をサポート
- IPopupHostProviderを実装し、PopupHostの変更通知を提供
- OverlayDismissEventPassThrough=trueで外部クリックを透過

---

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

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

### 推奨読解順序

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

ContextMenu関連のインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ISetterValue.cs | `src/Avalonia.Base/Styling/ISetterValue.cs` | Setter値インターフェース |
| 1-2 | IPopupHostProvider.cs | `src/Avalonia.Controls/Diagnostics/IPopupHostProvider.cs` | PopupHostプロバイダインターフェース |

**読解のコツ**: ISetterValueはContextMenuがSetterで使用できるようにするため、IPopupHostProviderはDevToolsなどがPopupHostを取得できるようにする。

#### Step 2: エントリーポイントを理解する

ContextMenuクラスを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ContextMenu.cs | `src/Avalonia.Controls/ContextMenu.cs` | プロパティ、Open/Close、イベント |

**主要処理フロー**:
1. **21行目**: MenuBaseを継承、ISetterValue/IPopupHostProviderを実装
2. **26-79行目**: 配置関連プロパティ定義
3. **106-112行目**: 静的コンストラクタでPlacement=Pointerをデフォルト設定
4. **188-195行目**: Opening/Closingイベント定義
5. **240-264行目**: Open(Control) - 指定コントロールでメニューを開く
6. **269-280行目**: Close() - メニューを閉じる
7. **301-349行目**: Open(内部) - Popup作成・設定・表示
8. **351-357行目**: PopupOpened - フォーカス保存・設定
9. **406-420行目**: ControlContextRequested - 右クリックイベントハンドリング

#### Step 3: 接続管理を理解する

Control.ContextMenuプロパティの変更ハンドリング。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ContextMenu.cs | `src/Avalonia.Controls/ContextMenu.cs` (201-225行目) | ContextMenuChanged |

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

```
ContextMenu
    │
    ├─ MenuBase (基底クラス)
    │      └─ IsOpen, Opened/Closed
    │
    ├─ Popup (_popup)
    │      ├─ IsLightDismissEnabled = true
    │      ├─ OverlayDismissEventPassThrough = true
    │      └─ 配置プロパティ
    │
    ├─ Control.ContextMenuProperty
    │      └─ 添付プロパティ経由で関連付け
    │
    ├─ ContextRequestedイベント
    │      └─ 右クリック/コンテキストキー
    │
    └─ Opening/Closingイベント
           └─ キャンセル可能
```

### データフロー図

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

右クリック ───▶ ContextRequested ───▶ Opening確認
                        │
                        ▼
                    Open() ───▶ Popup表示
                        │
                        ▼
                    Openedイベント
                        │
MenuItem選択 ───▶ コマンド実行 ───▶ Close()
                        │
外部クリック ───▶ Closing確認 ───▶ Close()
                        │
                        ▼
                    Closedイベント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ContextMenu.cs | `src/Avalonia.Controls/ContextMenu.cs` | ソース | ContextMenuコントロール本体 |
| MenuBase.cs | `src/Avalonia.Controls/MenuBase.cs` | ソース | 基底クラス |
| Popup.cs | `src/Avalonia.Controls/Primitives/Popup.cs` | ソース | ポップアップ表示 |
| MenuItem.cs | `src/Avalonia.Controls/MenuItem.cs` | ソース | メニュー項目 |
| Control.cs | `src/Avalonia.Controls/Control.cs` | ソース | ContextMenuProperty定義 |
