# 画面設計書 17-Clipboard

## 概要

本ドキュメントは、ControlCatalogアプリケーションにおけるClipboardページ（クリップボード操作のデモページ）の画面設計を記述したものである。

### 本画面の処理概要

ClipboardページはAvaloniaフレームワークのクリップボードAPIの機能をデモンストレーションするための画面である。テキスト、画像、ファイル、バイナリデータのコピー/ペースト操作、クリップボードフォーマットの取得、クリップボードのクリアなど、クリップボード関連の各種操作を確認できる。

**業務上の目的・背景**：コピー＆ペースト機能を実装するアプリケーション、ファイル転送機能、データ交換機能を持つアプリケーションを開発する開発者に対して、Avaloniaのクリップボード APIの使用方法を示す。テキストだけでなく、画像やファイル、カスタムバイナリデータの取り扱いも網羅している。

**画面へのアクセス方法**：MainWindow起動後、左側のHamburgerMenuから「Clipboard」を選択してアクセスする。

**主要な操作・処理内容**：
1. テキストのクリップボードへのコピー/ペースト
2. 画像のクリップボードへのコピー/ペースト
3. ファイルパスのクリップボードへのコピー/ペースト
4. バイナリデータのクリップボードへのコピー/ペースト
5. クリップボードに存在するフォーマットの取得
6. クリップボードのクリア
7. 自分のDataObjectがクリップボードに保持されているかの確認

**画面遷移**：MainViewのHamburgerMenuから遷移してくる。本画面から他画面への直接遷移はない。

**権限による表示制御**：本画面はデモ用途であり、権限による表示制御は実装されていない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 54 | DragDrop | 主機能 | クリップボード操作のデモ。コピー・ペースト機能 |

## 画面種別

デモ・サンプル画面（クリップボードAPIの機能展示）

## URL/ルーティング

ControlCatalogアプリケーション内のHamburgerMenuによるナビゲーション。URIベースのルーティングは使用していない。

## 入出力項目

| 項目名 | 種別 | データ型 | 必須 | 説明 |
|--------|------|----------|------|------|
| ClipboardContent | 入出力 | string | - | コピー元/ペースト先のテキスト |
| ClipboardImage | 出力 | IImage | - | ペーストした画像の表示 |
| OwnsClipboardDataObject | 出力 | string | - | 自分のデータがクリップボードにあるか（Yes/No） |

## 表示項目

| 要素 | コントロール | 説明 |
|------|--------------|------|
| Copy text | Button | テキストをクリップボードにコピー |
| Paste text | Button | クリップボードからテキストをペースト |
| Copy image | Button | 画像をクリップボードにコピー |
| Paste image | Button | クリップボードから画像をペースト |
| Copy files | Button | ファイルをクリップボードにコピー |
| Paste files | Button | クリップボードからファイルをペースト |
| Copy bytes | Button | バイナリデータをクリップボードにコピー |
| Paste bytes | Button | クリップボードからバイナリデータをペースト |
| Get formats | Button | クリップボードのフォーマット一覧を取得 |
| Clear | Button | クリップボードをクリア |
| OwnsClipboardDataObject | Run | 自分のDataObjectがクリップボードにあるか表示 |
| ClipboardContent | TextBox | テキスト入力/表示エリア |
| ClipboardImage | Image | 画像表示エリア（420x360） |

## イベント仕様

### 1-Copy text ボタンクリック

テキストボックスの内容をクリップボードにコピーする。

**処理フロー**:
1. CopyTextボタンのClickイベントが発火
2. TopLevel.GetTopLevel(this)?.Clipboardでクリップボードを取得
3. clipboard.SetTextAsync()でテキストを設定

**関連コード** (ClipboardPage.xaml.cs:44-47):
```csharp
private async void CopyText(object? sender, RoutedEventArgs args)
{
    if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
        await clipboard.SetTextAsync(ClipboardContent.Text ?? string.Empty);
}
```

### 2-Paste text ボタンクリック

クリップボードからテキストを取得してテキストボックスに表示する。

**処理フロー**:
1. PasteTextボタンのClickイベントが発火
2. clipboard.TryGetTextAsync()でテキストを取得
3. ClipboardContent.Textに設定

### 3-Copy image ボタンクリック

デフォルト画像をクリップボードにコピーする。

**処理フロー**:
1. CopyImageボタンのClickイベントが発火
2. clipboard.SetValueAsync(DataFormat.Bitmap, _defaultImage)で画像を設定

### 4-Paste image ボタンクリック

クリップボードから画像を取得して表示する。

**処理フロー**:
1. PasteImageボタンのClickイベントが発火
2. clipboard.TryGetDataAsync()でデータを取得
3. data.TryGetValueAsync(DataFormat.Bitmap)で画像を取得
4. ClipboardImage.Sourceに設定

### 5-Copy files ボタンクリック

テキストボックスに入力されたファイルパスをクリップボードにコピーする。

**処理フロー**:
1. CopyFilesボタンのClickイベントが発火
2. テキストを改行で分割してファイルパスリストを作成
3. StorageProviderでファイルの存在確認
4. DataTransferオブジェクトを作成してファイルを追加
5. clipboard.SetDataAsync()で設定
6. NotificationManagerで結果を通知

### 6-Paste files ボタンクリック

クリップボードからファイル一覧を取得する。

**処理フロー**:
1. PasteFilesボタンのClickイベントが発火
2. clipboard.TryGetFilesAsync()でファイルを取得
3. ローカルパスを改行区切りでテキストボックスに表示

### 7-Copy bytes ボタンクリック

10MBのランダムバイナリデータをクリップボードにコピーする。

**処理フロー**:
1. CopyBinaryDataボタンのClickイベントが発火
2. 10MB(10*1024*1024)のランダムバイト配列を生成
3. カスタムDataFormat（controlcatalog-binary-data）でDataTransferに追加
4. clipboard.SetDataAsync()で設定

### 8-Paste bytes ボタンクリック

クリップボードからバイナリデータを取得する。

**処理フロー**:
1. PasteBinaryDataボタンのClickイベントが発火
2. clipboard.TryGetValueAsync()でバイト配列を取得
3. テキストボックスにサイズを表示（例："10485760 bytes"）

### 9-Get formats ボタンクリック

クリップボードに存在するフォーマット一覧を取得する。

**処理フロー**:
1. GetFormatsボタンのClickイベントが発火
2. clipboard.GetDataFormatsAsync()でフォーマット一覧を取得
3. 改行区切りでテキストボックスに表示

### 10-Clear ボタンクリック

クリップボードをクリアする。

**処理フロー**:
1. ClearボタンのClickイベントが発火
2. clipboard.ClearAsync()でクリップボードをクリア

### 11-DataObject所有確認（タイマー処理）

0.5秒ごとにクリップボードに自分のDataObjectが保持されているか確認する。

**処理フロー**:
1. DispatcherTimerが0.5秒ごとにCheckLastDataObjectを呼び出す
2. clipboard.TryGetInProcessDataAsync()でDataTransferを取得
3. _storedDataTransferと比較
4. OwnsClipboardDataObjectのテキストと色を更新（Yes=Green、No=Red）

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

本画面はUIデモ用途であり、データベース操作は行わない。

## メッセージ仕様

| 種別 | メッセージ | 条件 |
|------|-----------|------|
| Warning | There is one o more invalid path. | ファイルコピー時に無効なパスが存在 |
| Success | Copy completed. | ファイルコピー成功 |
| Warning | Any files to copy in Clipboard. | コピーするファイルがない |

## 例外処理

- ファイルパスが存在しない場合は警告通知を表示
- クリップボードが取得できない場合は処理をスキップ

## 備考

- カスタムバイナリデータフォーマット名は"controlcatalog-binary-data"
- デフォルト画像は"/Assets/image1.jpg"
- VisualTreeへのアタッチ/デタッチでタイマーの開始/停止を制御

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ClipboardPage.xaml.cs | `samples/ControlCatalog/Pages/ClipboardPage.xaml.cs` | フィールド変数とDataFormat定義 |

**読解のコツ**:
- `_customBinaryDataFormat`: カスタムバイナリデータのフォーマット定義
- `_storedDataTransfer`: クリップボードにコピーしたDataTransferの参照保持
- `_defaultImage`: コピー用のデフォルト画像

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ClipboardPage.xaml.cs | `samples/ControlCatalog/Pages/ClipboardPage.xaml.cs` | コンストラクタとタイマー初期化 |

**主要処理フロー**:
1. **行33-35**: InitializeComponent()
2. **行36-37**: DispatcherTimer（0.5秒間隔）の作成
3. **行39-41**: デフォルト画像の読み込みと表示

#### Step 3: 各イベントハンドラを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ClipboardPage.xaml.cs | `samples/ControlCatalog/Pages/ClipboardPage.xaml.cs` | CopyText/PasteText等の実装 |

**主要処理フロー**:
- **行44-47**: CopyText - SetTextAsync
- **行49-54**: CopyImage - SetValueAsync(DataFormat.Bitmap)
- **行56-62**: PasteText - TryGetTextAsync
- **行64-76**: PasteImage - TryGetDataAsync + TryGetValueAsync(DataFormat.Bitmap)
- **行78-123**: CopyFiles - StorageProvider + DataTransfer
- **行125-133**: PasteFiles - TryGetFilesAsync
- **行144-153**: CopyBinaryData - Random.NextBytes
- **行156-162**: PasteBinaryData - TryGetValueAsync
- **行165-172**: Clear - ClearAsync

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

```
ClipboardPage
    │
    ├─ コンストラクタ
    │      ├─ InitializeComponent()
    │      ├─ DispatcherTimer作成
    │      └─ デフォルト画像読み込み
    │
    ├─ OnAttachedToVisualTree()
    │      └─ タイマー開始
    │
    ├─ OnDetachedFromVisualTree()
    │      └─ タイマー停止
    │
    ├─ CheckLastDataObject()（タイマー呼び出し）
    │      └─ TryGetInProcessDataAsync() → _storedDataTransferと比較
    │
    └─ 各ボタンイベント
           ├─ CopyText → SetTextAsync
           ├─ PasteText → TryGetTextAsync
           ├─ CopyImage → SetValueAsync
           ├─ PasteImage → TryGetValueAsync
           ├─ CopyFiles → SetDataAsync（DataTransfer）
           ├─ PasteFiles → TryGetFilesAsync
           ├─ CopyBinaryData → SetDataAsync（カスタムフォーマット）
           ├─ PasteBinaryData → TryGetValueAsync
           ├─ GetFormats → GetDataFormatsAsync
           └─ Clear → ClearAsync
```

### データフロー図

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

ClipboardContent.Text ───▶ SetTextAsync() ───▶ システムクリップボード
                     ◀─── TryGetTextAsync() ◀───

_defaultImage ───▶ SetValueAsync(Bitmap) ───▶ システムクリップボード
ClipboardImage ◀─── TryGetValueAsync(Bitmap) ◀───

FilePaths ───▶ DataTransfer作成 ───▶ SetDataAsync() ───▶ システムクリップボード
          ◀─── TryGetFilesAsync() ◀───

RandomBytes ───▶ DataTransfer(カスタム) ───▶ SetDataAsync() ───▶ システムクリップボード
            ◀─── TryGetValueAsync() ◀───
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ClipboardPage.xaml | `samples/ControlCatalog/Pages/ClipboardPage.xaml` | XAML | 画面レイアウト・ボタン定義 |
| ClipboardPage.xaml.cs | `samples/ControlCatalog/Pages/ClipboardPage.xaml.cs` | ソース | クリップボード操作ロジック |
| image1.jpg | `samples/ControlCatalog/Assets/image1.jpg` | 画像 | デフォルト画像（コピー用） |
| MainView.xaml | `samples/ControlCatalog/MainView.xaml` | XAML | ナビゲーション元のメインビュー |
