# 画面設計書 22-ContextMenu

## 概要

本ドキュメントは、Avalonia ControlCatalogサンプルアプリケーションにおけるContextMenuデモページの画面設計を定義するものです。

### 本画面の処理概要

本画面は、ContextMenu（コンテキストメニュー）コントロールの各種使用パターンをデモンストレーションするためのページです。右クリック時に表示されるポップアップメニューの実装方法を、開発者が学習・検証できる環境を提供します。

**業務上の目的・背景**：ContextMenuは、デスクトップアプリケーションにおける標準的なUXパターンであり、ユーザーが特定のコントロール上で右クリックした際にコンテキストに応じた操作メニューを表示します。WindowsやmacOSなど各プラットフォームでネイティブに期待されるユーザー体験を実現するために必要な機能です。ContextFlyoutとは異なり、従来のMenu/MenuItem構造を使用した標準的なコンテキストメニューを提供します。

**画面へのアクセス方法**：ControlCatalogアプリケーションのメインウィンドウから、HamburgerMenuのナビゲーションで「ContextMenu」を選択することでアクセスできます。

**主要な操作・処理内容**：
1. XAMLで定義されたContextMenuの表示（標準メニュー項目、無効化項目、サブメニュー、アイコン付き項目、チェックボックス付き項目、StaysOpenOnClick項目）
2. ViewModelを介した動的メニュー生成とバインディング
3. カスタムContextRequestedハンドラによるメニュー制御
4. Opening/Closingイベントのキャンセル機能

**画面遷移**：MainViewからHamburgerMenuナビゲーションを通じて遷移。画面内でのダイアログ表示（ファイルピッカー）機能あり。

**権限による表示制御**：特になし（サンプルアプリケーション）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | ContextMenu | 主機能 | コンテキストメニューのデモ。右クリックメニュー |

## 画面種別

デモ / サンプル表示

## URL/ルーティング

HamburgerMenu内部ナビゲーション（直接URLルーティングなし）

## 入出力項目

| 項目名 | 種別 | データ型 | 必須 | 説明 |
|--------|------|----------|------|------|
| CancelOpenCheckBox | 入力 | bool | - | メニューのオープンをキャンセルするかどうか |
| CancelCloseCheckBox | 入力 | bool | - | メニューのクローズをキャンセルするかどうか |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 説明テキスト | string | 「A right click menu that can be applied to any control.」 |
| デモ領域（Defined in XAML） | Border | XAMLで定義されたContextMenu |
| デモ領域（Dynamically Generated） | Border | ViewModelからバインドされた動的メニュー |
| デモ領域（Custom ContextRequested handler） | Border | カスタムハンドラでのポインター位置表示 |
| デモ領域（Cancellable） | Border | Opening/Closingキャンセル可能なContextMenu |

## イベント仕様

### 1-右クリック（Defined in XAML領域）

XAMLで定義されたContextMenuが表示される。メニュー項目：
- Standard Menu Item（Ctrl+A）
- Disabled Menu Item（無効化、Ctrl+D）
- Menu with Submenu（サブメニュー2階層）
- Menu Item with Icon（GitHubアイコン）
- Menu Item with Checkbox（チェックボックス付き）
- Menu Item that won't close on click（StaysOpenOnClick=True）

### 2-右クリック（Dynamically Generated領域）

ViewModelのMenuItemsコレクションからバインドされたメニューが表示される。Open/Save/Recentなどの項目が動的に構成される。

### 3-右クリック（Custom ContextRequested handler領域）

CustomContextRequestedハンドラが呼び出され、ポインター位置が取得・表示される。e.Handled=trueによりデフォルトのContextMenu表示が抑制される。

### 4-右クリック（Cancellable領域）

CancelOpenCheckBoxがチェックされている場合、Opening時にキャンセルされContextMenuが表示されない。CancelCloseCheckBoxがチェックされている場合、クリックしてもContextMenuが閉じない。

### 5-StaysOpenOnClick項目クリック

「Menu Item that won't close on click」をクリックしても、StaysOpenOnClick=Trueの設定により、ContextMenuは閉じない。

## データベース更新仕様

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

本画面はUIコントロールのデモであり、データベース操作は行いません。

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 表示条件 |
|------|-------------|---------------|----------|
| 情報 | - | Context was requested with pointer at: {X}, {Y} | Custom ContextRequested handler領域で右クリック時 |
| 情報 | - | Context was requested without pointer | キーボード操作でコンテキスト要求時 |

## 例外処理

- 特になし（デモ画面のため例外発生時はデバッグ出力のみ）

## 備考

- ContextMenuはContextFlyoutと異なり、従来のMenu/MenuItem構造を使用
- StaysOpenOnClick属性により、クリック後もメニューを開いたままにできる
- ContextFlyoutページと同じViewModelを共有している

---

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

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

### 推奨読解順序

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

まず、メニュー項目を表現するViewModelの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ContextPageViewModel.cs | `samples/ControlCatalog/ViewModels/ContextPageViewModel.cs` | MenuItemsコレクション、Open/Save/OpenRecentコマンドの定義（行12-43） |

**読解のコツ**: ContextFlyoutPageと同じViewModelを使用しているため、コードの再利用性を確認できます。

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

処理の起点となるUserControlとXAMLレイアウトを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ContextMenuPage.xaml | `samples/ControlCatalog/Pages/ContextMenuPage.xaml` | Border.ContextMenuプロパティへのContextMenu設定、スタイル定義、バインディング構文 |

**主要処理フロー**:
1. **行10-20**: UniformGrid.Stylesによる共通スタイル定義
2. **行21-49**: XAML定義のContextMenu（静的メニュー構成、StaysOpenOnClick属性）
3. **行50-63**: ViewModelバインドの動的ContextMenu
4. **行64-71**: カスタムContextRequestedハンドラ
5. **行72-86**: キャンセル可能なContextMenu

#### Step 3: コードビハインドを理解する

イベントハンドラとデータコンテキスト設定を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ContextMenuPage.xaml.cs | `samples/ControlCatalog/Pages/ContextMenuPage.xaml.cs` | コンストラクタでのDataContext設定、各イベントハンドラの実装 |

**主要処理フロー**:
- **行10-14**: コンストラクタでContextPageViewModelをDataContextに設定
- **行28-31**: ContextFlyoutPage_Closing - クローズキャンセル処理
- **行33-36**: ContextFlyoutPage_Opening - オープンキャンセル処理
- **行38-48**: CustomContextRequested - ポインター位置取得と表示

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

```
ContextMenuPage (UserControl)
    │
    ├─ コンストラクタ
    │      └─ ContextPageViewModel生成 → DataContext設定
    │
    ├─ XAML定義ContextMenu
    │      └─ MenuItem群（静的定義、StaysOpenOnClick属性）
    │
    ├─ 動的ContextMenu
    │      └─ MenuItems (ItemsSource) → MenuItemViewModel群
    │             ├─ OpenCommand → Open() → StorageProvider.OpenFilePickerAsync
    │             ├─ SaveCommand → Save() → Debug出力
    │             └─ OpenRecentCommand → OpenRecent(path)
    │
    ├─ CustomContextRequested
    │      └─ TryGetPosition() → TextBlock.Text更新
    │
    └─ Opening/Closingイベント
           └─ CancelEventArgs.Cancel設定
```

### データフロー図

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

右クリック ───────────▶ ContextRequested発生 ───────────▶ ContextMenu表示
                              │
                              └─ e.Handled=true時 ─────▶ カスタム処理

CheckBox状態 ───────────▶ Opening/Closingハンドラ ──────▶ キャンセル判定
                              │
                              └─ e.Cancel=true時 ──────▶ 表示/非表示制御

MenuItem Click ─────────▶ StaysOpenOnClick判定 ─────────▶ メニュー維持/閉じる
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ContextMenuPage.xaml | `samples/ControlCatalog/Pages/ContextMenuPage.xaml` | XAML | 画面レイアウト定義 |
| ContextMenuPage.xaml.cs | `samples/ControlCatalog/Pages/ContextMenuPage.xaml.cs` | ソース | コードビハインド、イベントハンドラ |
| ContextPageViewModel.cs | `samples/ControlCatalog/ViewModels/ContextPageViewModel.cs` | ソース | メニュー項目とコマンドの定義 |
| github_icon.png | `samples/ControlCatalog/Assets/github_icon.png` | アセット | メニューアイコン画像 |
