マスタ検索画面枠線統一実装手順書.md

# マスタ検索画面枠線統一とボタン配置実装手順書

## 概要
マスタ検索画面において、検索欄の枠線とグリッドの枠線の横幅を統一し、「戻る」ボタンと「新規作成」ボタンをこれらの枠線の延長線上に配置します。

## 現状の分析

### 現在の構成
1. **検索欄(SearchBoxControl等)**
   - 枠線付きパネル(panelSearchBox)を使用
   - BorderStyle.FixedSingleで枠線を表示
   - パネルの幅がコントロールによって異なる可能性

2. **グリッド(CustomerDgvControl等)**
   - DataGridViewを使用
   - 枠線の幅が検索欄と異なる可能性

3. **ボタン(BtnAddMasterControl)**
   - 「戻る」ボタンと「新規作成」ボタンを含む
   - 配置が枠線と揃っていない可能性

### 問題点
- 検索欄とグリッドの枠線の幅が異なる
- ボタンの配置が枠線と揃っていない
- 画面全体の統一感が欠けている

## 修正方針

### 目標
1. 検索欄とグリッドの枠線の横幅を統一
2. ボタンを枠線の延長線上に配置
3. 画面全体の見た目の統一感を向上

### 実装方法
1. TableLayoutPanelの列幅を調整して、すべてのコントロールの幅を統一
2. ボタンコントロールの配置を調整

## 実装手順

### ステップ1: 各マスタ画面のTableLayoutPanel設定確認

#### 1.1 M_CustomerMaster.Designer.csの現状確認

現在のTableLayoutPanelの設定:
```csharp
this.tableLayoutPanel.ColumnCount = 3;
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
```

この設定により、検索欄、グリッド、ボタンはすべて同じ幅(中央の列)に配置されるはずですが、各コントロール内での余白設定により見た目が異なる可能性があります。

### ステップ2: 各ユーザーコントロール内の余白調整

#### 2.1 SearchBoxControl.Designer.csの修正

検索欄の枠線位置を調整:
```csharp
// panelSearchBox
// 
this.panelSearchBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
| System.Windows.Forms.AnchorStyles.Left) 
| System.Windows.Forms.AnchorStyles.Right)));
this.panelSearchBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panelSearchBox.Controls.Add(this.btnSearch);
this.panelSearchBox.Controls.Add(this.chkUnusedData);
this.panelSearchBox.Controls.Add(this.tlpSearchPattrern);
this.panelSearchBox.Controls.Add(this.tableLayoutPanel1);
this.panelSearchBox.Location = new System.Drawing.Point(0, 39); // 左余白を0に変更
this.panelSearchBox.Name = "panelSearchBox";
this.panelSearchBox.Size = new System.Drawing.Size(1540, 165); // 幅を親コントロールに合わせる
this.panelSearchBox.TabIndex = 4;
```

#### 2.2 CustomerDgvControl等のグリッドコントロールの調整

グリッドコントロールのDockプロパティがFillに設定されていることを確認し、余白がないようにします。

### ステップ3: BtnAddMasterControlの配置調整

#### 3.1 ボタンの配置を左右端に揃える

BtnAddMasterControl内で、「戻る」ボタンを左端、「新規作成」ボタンを右端に配置:

```csharp
// 戻るボタン
btnReturn.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
btnReturn.Location = new Point(0, Y座標);

// 新規作成ボタン
btnCreateAdd.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
btnCreateAdd.Location = new Point(親の幅 - ボタン幅, Y座標);
```

### ステップ4: 動的な調整を行うヘルパーメソッドの作成

#### 4.1 LayoutAdjustmentHelper.csの作成

```csharp
using System.Windows.Forms;
using System.Drawing;

namespace ChatworkBulkSender.Utils
{
    /// <summary>
    /// マスタ画面のレイアウトを統一するヘルパークラス
    /// </summary>
    public static class LayoutAdjustmentHelper
    {
        /// <summary>
        /// マスタ画面の枠線とボタン配置を統一
        /// </summary>
        public static void AdjustMasterScreenLayout(Form form, 
            Control searchBoxControl, 
            Control dgvControl, 
            Control btnControl)
        {
            // nullチェック
            if (form == null || searchBoxControl == null || 
                dgvControl == null || btnControl == null) return;
            
            // 検索ボックス内の枠線パネルを探す
            Panel searchPanel = FindPanelWithBorder(searchBoxControl);
            if (searchPanel != null)
            {
                // 左右の余白を0に設定
                searchPanel.Location = new Point(0, searchPanel.Location.Y);
                searchPanel.Width = searchBoxControl.Width;
            }
            
            // DataGridViewの枠線スタイルを統一
            DataGridView dgv = FindDataGridView(dgvControl);
            if (dgv != null)
            {
                dgv.BorderStyle = BorderStyle.FixedSingle;
            }
            
            // ボタンの配置を調整
            AdjustButtonPositions(btnControl);
        }
        
        /// <summary>
        /// 枠線を持つパネルを検索
        /// </summary>
        private static Panel FindPanelWithBorder(Control parent)
        {
            foreach (Control control in parent.Controls)
            {
                if (control is Panel panel && panel.BorderStyle != BorderStyle.None)
                {
                    return panel;
                }
                
                // 再帰的に検索
                Panel found = FindPanelWithBorder(control);
                if (found != null) return found;
            }
            return null;
        }
        
        /// <summary>
        /// DataGridViewを検索
        /// </summary>
        private static DataGridView FindDataGridView(Control parent)
        {
            foreach (Control control in parent.Controls)
            {
                if (control is DataGridView dgv)
                {
                    return dgv;
                }
                
                // 再帰的に検索
                DataGridView found = FindDataGridView(control);
                if (found != null) return found;
            }
            return null;
        }
        
        /// <summary>
        /// ボタンの位置を調整
        /// </summary>
        private static void AdjustButtonPositions(Control btnControl)
        {
            Button btnReturn = null;
            Button btnCreate = null;
            
            // ボタンを探す
            foreach (Control control in btnControl.Controls)
            {
                if (control is Button btn)
                {
                    if (btn.Text.Contains("戻る"))
                    {
                        btnReturn = btn;
                    }
                    else if (btn.Text.Contains("新規"))
                    {
                        btnCreate = btn;
                    }
                }
            }
            
            // ボタンの位置を調整
            if (btnReturn != null)
            {
                btnReturn.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
                btnReturn.Location = new Point(0, btnReturn.Location.Y);
            }
            
            if (btnCreate != null)
            {
                btnCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
                btnCreate.Location = new Point(
                    btnControl.Width - btnCreate.Width, 
                    btnCreate.Location.Y);
            }
        }
    }
}
```

### ステップ5: 各マスタ画面での適用

#### 5.1 M_CustomerMaster.csの修正

```csharp
private void M_CustomerMaster_Load(object sender, EventArgs e)
{
    // 既存のコード...
    
    // レイアウトの調整
    LayoutAdjustmentHelper.AdjustMasterScreenLayout(
        this, 
        _searchBoxControl, 
        _customerDgvControl, 
        _btnControl);
}
```

## テストシナリオ

### シナリオ1: 枠線の確認
1. 各マスタ画面を開く
2. 検索欄の枠線とグリッドの枠線の左右端が揃っていることを確認
3. 枠線の太さが統一されていることを確認

### シナリオ2: ボタン配置の確認
1. 「戻る」ボタンが枠線の左端に揃っていることを確認
2. 「新規作成」ボタンが枠線の右端に揃っていることを確認

### シナリオ3: ウィンドウサイズ変更時の動作
1. ウィンドウサイズを変更(可能な場合)
2. 枠線とボタンの配置が維持されることを確認

## 実装の注意点

### 1. Anchorプロパティの設定
適切なAnchorプロパティを設定することで、ウィンドウサイズが変更されても配置が維持されます。

### 2. DockプロパティとLocationプロパティの併用
DockプロパティがFillに設定されている場合、Locationプロパティは無視されるため注意が必要です。

### 3. Designer.csファイルの直接編集
Visual Studioのデザイナーで変更を行うと、手動編集が上書きされる可能性があるため、動的な調整を推奨します。

## 実装チェックリスト

### LayoutAdjustmentHelper.cs
- [ ] クラスの作成
- [ ] AdjustMasterScreenLayoutメソッドの実装
- [ ] FindPanelWithBorderメソッドの実装
- [ ] FindDataGridViewメソッドの実装
- [ ] AdjustButtonPositionsメソッドの実装

### 各マスタ画面
- [ ] M_CustomerMaster.csへの適用
- [ ] M_SendPatternMaster.csへの適用
- [ ] M_SenderMaster.csへの適用(該当する場合)

### 動作確認
- [ ] 検索欄とグリッドの枠線が揃っていること
- [ ] ボタンが枠線の延長線上に配置されていること
- [ ] すべてのマスタ画面で統一された見た目になっていること

## まとめ

この修正により、マスタ検索画面の枠線とボタン配置が統一され、見た目の一貫性が向上します。ユーザーにとって、より見やすく使いやすい画面になります。