C#のWindowsフォームアプリでフォーム間でデータを共有する方法

#概要
C#でWindowsフォームアプリケーションを作成するときにstaticなクラスを使ってフォーム間でデータを共有してみます。（例えばログイン後にログイン情報を使いまわす）

#画面と動作のイメージ
##ログイン画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208266/a01dfc03-43c3-8b0d-025d-fba8acfb51a4.png)

##ログイン後の画面
赤線の部分が共有データを使って表示している箇所。
お値段に整数を入力して計算ボタンをクリックすると会員ランクに設定されたレートで計算結果が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208266/c1f60d0f-25b2-5cef-ce48-4456ece6c708.png)

#手順
##Windowsフォームアプリケーションを選択
プロジェクト名はなんでもOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208266/04bf6acc-6b98-5800-8592-02c4902dd720.png)

##Interfaceファイルを作成
1. ソリューションエクスプローラーでプロジェクトを右クリック
1. 追加
1. クラスをクリック
1. インターフェースを選択して、名前をIRank.csで追加をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208266/e959deeb-6313-263e-09cd-b53f9269b998.png)

###IRank.csファイルのコードを編集
Interfaceを使ってランクを切り替える仕組みです。

```C#:IRank.cs
namespace WindowsFormsApp4
{
    public interface IRank
    {
        float Rate { get; }
        string GetRank();
    }

    class Free : IRank
    {
        public float Rate => 1.0f;

        public string GetRank()
        {
            return "無料";
        }
    }

    class Biz : IRank
    {
        public float Rate => 0.5f;

        public string GetRank()
        {
            return "有料";
        }
    }
}
```

##フォーム間でデータを共有するStaticなクラスを作成
ここにログイン情報が格納されて使いまわしが可能になる

```C#:LoginInfo.cs
namespace WindowsFormsApp4
{
    public static class LoginInfo
    {
        public static IRank Rank { get; set; }
    }
}
```

##LoginInfoへ格納するインスタンスを作成するFactoryを作成

```C#:LoginInfoFactory.cs
namespace WindowsFormsApp4
{
    static class LoginInfoFactory
    {
        public enum Rank
        {
            Free,
            Biz
        }

        internal static IRank Create(Rank rank)
        {
            if (rank == Rank.Free)
            {
                return new Free();
            }
            return new Biz();
        }
    }
}
```

##ログイン後に表示するフォームを作成

1. ソリューションエクスプローラーでプロジェクトを右クリック
1. 追加
1. フォーム（Windowsフォーム）をクリック
1. ファイル名はPriceForm.cs
1. UIはこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208266/ea368dca-87ec-ad41-b2a7-b5fb58105650.png)

###PriceForm.csのコードを編集

```C#:PriceForm.cs
using System;
using System.Windows.Forms;

namespace WindowsFormsApp4
{
    public partial class PriceForm : Form
    {
        public PriceForm()
        {
            InitializeComponent();
            var rankStr = LoginInfo.Rank.GetRank();
            this.Text = rankStr;
            RankLabel.Text = rankStr;
            var IniPrice = 100;
            textBox1.Text = IniPrice.ToString();
            Result.Text = (IniPrice * LoginInfo.Rank.Rate) + "円です。";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var price = Convert.ToInt32(textBox1.Text);
            textBox1.Text = price.ToString();
            Result.Text = (price * LoginInfo.Rank.Rate) + "円です。";
        }
    }
}
```

##デフォルトで作成されているForm1を編集

1. ソリューションエクスプローラーでForm1.csの名前をLoginForm.csへ変更
1. UIはこんな感じで配置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208266/2d9a1f4a-ece2-9a20-5e18-85e9cbdb7386.png)


##LoginForm.csのコードを編集

```C#:LoginForm.cs
using System;
using System.Windows.Forms;

namespace WindowsFormsApp4
{
    public partial class RankForm : Form
    {
        public RankForm()
        {
            InitializeComponent();
        }

        private void LoginButton_Click(object sender, EventArgs e)
        {
            if (FreeButton.Checked)
            {
                LoginInfo.Rank = LoginInfoFactory.Create(LoginInfoFactory.Rank.Free);
            }
            else
            {
                LoginInfo.Rank = LoginInfoFactory.Create(LoginInfoFactory.Rank.Biz);
            }

            using (var f = new PriceForm())
            {
                f.ShowDialog();
            }
        }
    }
}
```

##最終的なファイルの構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208266/078246cd-1664-732d-36eb-3e9c5dd4ecaf.png)


#おわり
さらにフォームを増やしてもLoginInfoを使えばデータを共有できます。