# 画面設計書 12-ButtonSpinner

## 概要

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

### 本画面の処理概要

ButtonSpinnerページはAvaloniaフレームワークのButtonSpinnerコントロールの機能をデモンストレーションするための画面である。ButtonSpinnerは任意の要素にスピンボタン（上下ボタン）を追加し、Spinイベントを通じてその要素を操作できるようにするコントロールである。

**業務上の目的・背景**：数値入力やリスト項目の順次選択など、上下ボタンによる値の増減操作が必要なUIを実装する開発者に対して、ButtonSpinnerコントロールの使用方法を視覚的に示す。NumericUpDownコントロールの内部でも使用される基盤コントロールであり、カスタムスピナー実装の参考となる。

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

**主要な操作・処理内容**：
1. スピンボタン（上下矢印）のクリックによるテキスト内容の変更
2. AllowSpinプロパティによるスピン操作の有効/無効切り替え
3. ShowButtonSpinnerプロパティによるスピンボタン表示/非表示切り替え
4. ButtonSpinnerLocationプロパティによるボタン配置位置（左右）の確認

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

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | NumericUpDown | 主機能 | ButtonSpinnerコントロールのデモ。スピンボタンによる値増減 |

## 画面種別

デモ・サンプル画面（ButtonSpinnerコントロールの機能展示）

## URL/ルーティング

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

## 入出力項目

| 項目名 | 種別 | データ型 | 必須 | 説明 |
|--------|------|----------|------|------|
| allowSpinCheck | 入力 | bool | - | AllowSpinプロパティのバインディング元 |
| showSpinCheck | 入力 | bool | - | ShowButtonSpinnerプロパティのバインディング元 |
| 山名テキスト | 出力 | string | - | スピン操作で変化する山名（Everest等） |

## 表示項目

| セクション | コントロール | 説明 |
|------------|--------------|------|
| ヘッダー | TextBlock | コントロールの説明文 |
| AllowSpin | CheckBox | スピン操作の有効/無効を切り替え（初期値：チェック済み） |
| ShowButtonSpinner | CheckBox | スピンボタンの表示/非表示を切り替え（初期値：チェック済み） |
| ButtonSpinner (右配置) | ButtonSpinner | スピンボタンが右側に配置されたバージョン |
| ButtonSpinner (左配置) | ButtonSpinner | ButtonSpinnerLocation="Left"でスピンボタンが左側に配置 |
| ButtonSpinner (エラー付き) | ButtonSpinner | DataValidationErrors.Errorが設定されたバージョン |

## イベント仕様

### 1-Spin イベント

ButtonSpinnerのスピンボタン（上下矢印）をクリックすると、Spinイベントが発火する。

**処理フロー**:
1. ユーザーがスピンボタンをクリック
2. Spinイベントが発火し、OnSpinハンドラが呼び出される
3. SpinEventArgs.Directionに基づき、Increaseなら次の山名、Decreaseなら前の山名を選択
4. 配列の境界を超える場合はラップアラウンド（循環）する
5. TextBlockのTextプロパティを更新

**関連コード** (ButtonSpinnerPage.xaml.cs:13-32):
```csharp
public void OnSpin(object sender, SpinEventArgs e)
{
    var spinner = (ButtonSpinner)sender;

    if (spinner.Content is TextBlock txtBox)
    {
        int value = Array.IndexOf(_mountains, txtBox.Text);
        if (e.Direction == SpinDirection.Increase)
            value++;
        else
            value--;

        if (value < 0)
            value = _mountains.Length - 1;
        else if (value >= _mountains.Length)
            value = 0;

        txtBox.Text = _mountains[value];
    }
}
```

**データ（山名リスト）**:
- Everest
- K2 (Mount Godwin Austen)
- Kangchenjunga
- Lhotse
- Makalu
- Cho Oyu
- Dhaulagiri
- Manaslu
- Nanga Parbat
- Annapurna

### 2-AllowSpin チェックボックス変更

AllowSpinチェックボックスの状態変更により、ButtonSpinnerのAllowSpinプロパティがバインディングで更新される。

**処理フロー**:
1. ユーザーがallowSpinCheckチェックボックスをクリック
2. IsCheckedプロパティが変更される
3. バインディング `{Binding #allowSpinCheck.IsChecked}` により3つのButtonSpinnerのAllowSpinプロパティが更新
4. AllowSpin=falseの場合、スピンボタンがクリック不可になる

### 3-ShowButtonSpinner チェックボックス変更

ShowButtonSpinnerチェックボックスの状態変更により、ButtonSpinnerのShowButtonSpinnerプロパティがバインディングで更新される。

**処理フロー**:
1. ユーザーがshowSpinCheckチェックボックスをクリック
2. IsCheckedプロパティが変更される
3. バインディング `{Binding #showSpinCheck.IsChecked}` により3つのButtonSpinnerのShowButtonSpinnerプロパティが更新
4. ShowButtonSpinner=falseの場合、スピンボタンが非表示になる

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

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

## メッセージ仕様

本画面では特定のメッセージ表示は実装されていない。

## 例外処理

- DataValidationErrors.Errorが設定されたButtonSpinnerでは、Exceptionオブジェクトが設定されており、バリデーションエラー表示のデモを行っている。

## 備考

- ButtonSpinnerはNumericUpDownの内部で使用されるコントロールであり、単独で使用することでカスタムスピナーUIを構築できる
- ButtonSpinnerLocationプロパティで Left または Right（デフォルト）を指定可能
- Height/MinHeightプロパティでスピナーの高さを制御

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ButtonSpinnerPage.xaml.cs | `samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml.cs` | _mountains配列による山名リストの定義 |

**読解のコツ**: _mountains配列は読み取り専用のstring配列で、世界の高山トップ10の名前を格納している。スピン操作でこの配列を循環する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ButtonSpinnerPage.xaml | `samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml` | UserControlのレイアウト構造 |

**主要処理フロー**:
1. **行1-4**: UserControl定義とSystem名前空間のインポート
2. **行6-7**: 説明テキストの表示
3. **行9-11**: CheckBoxによるプロパティ制御UI
4. **行12-29**: 3種類のButtonSpinnerの配置

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ButtonSpinnerPage.xaml.cs | `samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml.cs` | OnSpinメソッドの実装 |

**主要処理フロー**:
- **行13-32**: OnSpinイベントハンドラ
  - **行15**: sender を ButtonSpinner にキャスト
  - **行17**: Content が TextBlock かどうかを確認
  - **行19**: 現在の山名のインデックスを取得
  - **行20-23**: SpinDirectionに応じてインデックスを増減
  - **行25-28**: 境界チェックとラップアラウンド処理
  - **行30**: TextBlockのTextを更新

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

```
ButtonSpinnerPage
    │
    ├─ InitializeComponent()
    │      └─ XAML解析・コントロール初期化
    │
    └─ OnSpin(sender, SpinEventArgs)
           ├─ Array.IndexOf(_mountains, txtBox.Text)
           ├─ Direction判定（Increase/Decrease）
           ├─ 境界チェック・ラップアラウンド
           └─ txtBox.Text = _mountains[value]
```

### データフロー図

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

SpinButton.Click ───▶ OnSpin() ───▶ TextBlock.Text
                           │
                           ├─ SpinDirection.Increase → value++
                           └─ SpinDirection.Decrease → value--
                                    │
                                    └─ 境界チェック（循環）

CheckBox.IsChecked ───▶ Binding ───▶ ButtonSpinner.AllowSpin
                                      ButtonSpinner.ShowButtonSpinner
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ButtonSpinnerPage.xaml | `samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml` | XAML | 画面レイアウト・コントロール定義 |
| ButtonSpinnerPage.xaml.cs | `samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml.cs` | ソース | コードビハインド・イベントハンドラ・データ定義 |
| MainView.xaml | `samples/ControlCatalog/MainView.xaml` | XAML | ナビゲーション元のメインビュー |
