[Windows Forms] ボタンに画像を2つ表示

# ■概要

画像を2つ設定したボタン
![00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/bb277726-9e8f-2317-d55c-4c21f1a0bbbf.png)

# ■環境

* Windows 10
* Visual Studio 2019 Community Version 16.9.2
* .NET Framework 4.7.2

# ■プロジェクトの作成

新しいプロジェクトを作成します。
検索条件で絞り込んで`Windows フォーム アプリケーション(.NET Framework)`を選択します。
![01_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/1f5796c6-fb30-5286-e94a-fbbaa4d11b26.png)

プロジェクト名を入力し、フレームワークを選択します。
ここではプロジェクト名を`WindowsFormsApp1`、
フレームワークは4.5～4.8、ここでは`.NET Framework 4.7.2`にしました。
![02_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/59d5ab5f-09aa-c80e-8327-665fdbf69944.png)

![03_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/d831cbaf-8b9a-8609-0f8c-72825affae07.png)

# ■画面コンテンツ枠の追加

プロジェクトを右クリックし、「追加」-「新しい項目」を選択します。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/6aa85f86-d8cd-38cc-0330-02f7624db2ad.png)

「WPF」-「ユーザーコントロール(WPF)」を選択し、名前に`Form1Child`と入力して追加します。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/824c2b2a-b9fd-5583-f078-082203f030b9.png)
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/b91e137d-a606-9817-5707-6c151d5132c1.png)

メニューの「ビルド」-「ソリューションのビルド」でビルドしておきます。

Form1を選択し、ツールボックスの「WPF相互運用機能」の「ElementHost」をForm1にドラッグ＆ドロップします。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/586cb0d0-118a-5227-4604-1dd025404b5e.png)

「ホストするコンテンツの選択」のドロップダウンを開き、`Form1Child`を選択します。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/de20d466-fb64-3de2-73fd-dd64e155ad7f.png)

「親コンテナーにドッキングする」を選択します。
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/941dd027-2077-20c2-9150-fc83a13a98ab.png)
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/099e2d02-8203-7db5-5d7c-72b1daed0af6.png)

# ■土台部分作成

デザイナの「Form1Child.xaml」のタブを選択し、メニューの「表示」-「その他のウィンドウ」-「ドキュメントアウトライン」を選択します。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/693170bb-8882-4967-1fa1-9e426a820dd6.png)

ドキュメントアウトラインを使いやすい位置に配置します。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/afe226b0-de53-95a3-dfc9-6369d26b77a7.png)

Gridを選択状態にし、デザイナの薄く赤線を引いた部分にマウスポインタを近づけると`+`マークが付きます。
そこでクリックするとGridを分割できます。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/9e2257ec-dfc0-5e24-e562-8720fa773882.png)
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/a3823625-df93-ccc6-c17f-e1e2d346afe9.png)

ツールボックスから「StackPanel」を行分割したGridの下の行にドラッグ＆ドロップします。
![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/1b52547c-6994-8e2c-c837-9c476e15ef8f.png)

Gridの中にStackPanelが追加されました。
![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/c15f7d3a-468c-026e-98e4-58bb9e0772ff.png)

StackPanelは既定では中に配置したコントロールを縦並びに整列させます。
これを横並びに変更します。
StackPanelを選択し、プロパティウィンドウの「整列」-「Orientation」で`Horizontal`を選択します。
![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/3a306eaa-408c-6dae-2017-81e13861fcc6.png)

# ■ボタンの追加

ツールボックスから「Button」を画面のStackPanel上にドラッグ＆ドロップします。
![23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/c1a48a64-89c6-c6d6-10cd-76723768cde6.png)

続けて2つ、「Button」をStackPanel上にドラッグ＆ドロップします。
![24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/921865fb-934f-3a55-e783-8d1c2ce0bdf0.png)
![25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/e9fbe33b-ee94-0989-e416-70e64f24331a.png)

# ■画像リソースの読み込み

以下のファイルをダウンロードして`green.png`, `orange.png`という名前で保存します。
![green.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/6f02f500-a3a6-8c55-42a2-0c46ff1b09ca.png)
![orange.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/9890ffe9-13d8-7abd-5037-85c616d0f2bd.png)

プロジェクトの「Properties」-「Resources.resx」をダブルクリックし、
「リソースの追加」の`▼`をクリックし、「既存のファイルの追加」を選択します。
![26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/3a8876e5-4051-fe7e-cc27-9bc30391c1aa.png)

green.pngとorange.pngを追加します。
![27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/5e5c3e6f-773d-4e91-80bf-db700e7f541f.png)

「Resources」フォルダの「green.png」を選択し、
プロパティウィンドウの「ビルドアクション」で`Resources`を選択します。
![28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/3a1a388f-9cec-ffbf-dda1-f958fbf03b17.png)

「orange.png」も同様に設定します。
![29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/7fcf417e-5c96-f2e4-75a6-ba4a1ec1d746.png)

メニューの「ビルド」-「ソリューションのビルド」でビルドしておきます。

# ■画像付きボタンの作成

## ◇部品配置

ツールボックスから「StackPanel」を1つめのボタン上にドラッグ＆ドロップします。
![30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/90769547-356c-916e-3d01-c0fbf35c6943.png)

ボタンの中にStackPanelが入りました。
![31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/6f7bf244-ffa6-8ea5-6fe0-07b0beacf66f.png)

ドキュメントアウトライン上でStackPanelが選択状態になっていることを確認し、
プロパティウィンドウで「レイアウト」-「Orientation」を先程と同じ`Horizontal`に設定します。

ツールボックスからドキュメントアウトラインの「Button」の中の「StackPanel」上に、
「Image」、「TextBlock」、「Image」の順にドラッグ＆ドロップします。
![32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/ace9aff5-6ee8-9f67-8e1f-db50e873c93e.png)
![33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/ebd13c10-e400-363f-9d3e-70a8fece49d4.png)

## ◇画像設定

ドキュメントアウトラインで1つめの「Image」を選択し、
プロパティウィンドウの「共通」-「Source」の`▼`を開き、「green.png」を選択します。
![34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/a4140fc6-390f-0275-6fd5-732a1ae30893.png)

「Image」をプロパティウィンドウの「レイアウト」で「Width」と「Height」を`20`に設定します。
![35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/2c4cffaf-e61d-14a2-fc5c-a1193e470ae4.png)

もう一つの「Image」も「orange.png」を読み込ませて同様に設定します。
![36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/50b8b1ba-97e6-e8fe-ccad-9bd074448bbe.png)

## ◇余白調整、ボタンテキスト変更

ドキュメントアウトラインで「TextBlock」を選択し、
プロパティウィンドウの「レイアウト」-「Margin」で左右余白`8`を設定します。
「共通」-「Text」に`押してください`を入力します。
![37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/9bc2b1d6-ad9c-ca08-bf35-be4a5f220d79.png)
「レイアウト」-「VerticalAlignment」を`Center`に設定します。
![37-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/f449676f-03c8-444a-37cc-a5f1372e506e.png)

## ◇イベント追加

ドキュメントアウトラインで1つめのボタンを選択し、プロパティウィンドウで稲妻マークを選択し、イベント一覧を表示します。
「Click」横のテキストボックスをダブルクリックします。
![38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/c512f582-e769-0ff4-6796-9fea6bcb947d.png)

メッセージボックスを表示する処理を記述します。

```csharp:Form1Child.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("押された！", "タイトル", 
        MessageBoxButton.OK, MessageBoxImage.Information);
}
```

# ■Gridの行高さ調整

適当に設定していたGridの行高さを調整します。
ドキュメントアウトラインでGridを選択し、デザイナでGridの下の行の左端あたりにマウスポインタを移動します。
![40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/abad7b00-cc00-46e1-43ae-62dbc80af592.png)

ドロップダウンを開いて「Auto」を選択します。
![41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/0b01f974-e542-5a4f-57ff-547c149b1f0a.png)

Grid行の中の要素（ボタン）に合わせて自動調整されます。
![42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/29529bc3-8d42-2e11-57d7-ea749369fbf6.png)

# ■ボタン間隔調整

ボタンがぴったりくっついているので間隔を調整します。
以下をUserControlの開始タグとGridの開始タグの間に記述します。

```xml:Form1Child.xaml
<UserControl.Resources>
    <Style TargetType="Button">
        <Setter Property="Margin" Value="8" />
    </Style>
</UserControl.Resources>
```

これでこのUserControlの中にあるすべてのボタンの上下左右に余白`8`が設定されました。
![43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/cf2e17f6-36e2-0701-8341-872f8168a8ad.png)

ボタンの淵と中身の間隔「Padding」も設定してみます。

```xml
<Style TargetType="Button">
    <Setter Property="Margin" Value="8" />
    <Setter Property="Padding" Value="24,8" />
</Style>
```

![44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/655a0cbe-0a80-676c-71bf-229a0b3487d1.png)

ボタンの淵～中身の左右の間隔は`24`、上下間隔は`8`に設定しました。
![45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/5aa9b914-8844-d45f-9729-e007abefc5a1.png)

# ■実行

![46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/197093f7-7ce0-2e0b-3f6c-9a6c11fb4c8c.png)

# ■おまけ

閉じるボタンを実装します。
3つめのボタンのテキストを`閉じる`にし、Clickイベントに`CloseButton_Click`を入力してEnterします。
![50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/2726bd4a-aeac-46e7-90a5-49031aa79a4a.png)

プロパティ`CloseAction`を追加し、CloseButton_Clickの中で呼び出します。

```csharp:Form1Child.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;

namespace WindowsFormsApp1
{
    /// <summary>
    /// Form1Child.xaml の相互作用ロジック
    /// </summary>
    public partial class Form1Child : UserControl
    {
        public Action CloseAction { get; set; }

        public Form1Child()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("押された！", "タイトル", 
                MessageBoxButton.OK, MessageBoxImage.Information);
        }

        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            CloseAction();
        }
    }
}
```

CloseActionにフォームを閉じる処理を設定します。

```csharp:Form1.cs
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            var child = elementHost1.Child as Form1Child;
            child.CloseAction = () => Close();
        }
    }
}
```