プログラム初心者勉強会　6回目　-C# Windowsフォーム入門

#目次
[1. 前回リンク](#1-前回リンク)
[2. 次回リンク](#2-次回リンク)
[3. やったこと](#3-やったこと)
[4. 配信時の録画](#4-配信時の録画)
[5. 今回学んだこと](#5-今回学んだこと)
[6. モーダルダイアログ、モーダレスダイアログ](#6-モーダルダイアログ、モーダレスダイアログ)
[7. ダイアログ上のボタンイベント結果取得について](#7-ダイアログ上のボタンイベント結果取得について)
[8. ダイアログ上のチェックボックスやテキストボックスの状態取得](#8-ダイアログ上のチェックボックスやテキストボックスの状態取得)
[9. 振り返り](#9-振り返り)
[10. 次回予告](#10-次回予告)

#1. 前回リンク
https://qiita.com/Usyuuu-program-beginner/items/1e2a2bddacceaa17455c

#2. 次回リンク
https://qiita.com/Usyuuu-program-beginner/items/570f850fd4dbfae4b68d

#3. やったこと
下のサイトの 9. ダイアログ(1)を学習

http://kaitei.net/csforms/

#4. 配信時の録画
https://www.youtube.com/watch?v=6YnJGzY0f7o

#5. 今回学んだこと
ダイアログの勉強が生放送中にあまり進まなかったので、オフで学んだことも書いてこうかなと思う

#6. モーダルダイアログ、モーダレスダイアログ
##6.1 それぞれの意味について
###6.1.1 モーダルダイアログとは
ダイアログを開いた場合、親ウィンドウの操作が無効となる

###6.1.2 モーダレスダイアログとは
ダイアログを開いた場合、親ウィンドウの操作が有効となる

##6.2 ダイアログの表示方法について
###6.2.1 モーダルダイアログの表示
ダイアログのインスタンス化を行った後、**ShowDialog()**を使用して表示する

##6.2.2 モーダレスダイアログの表示
ダイアログのインスタンス化を行った後、
1. **(ダイアログのインスタンス名）.Owner = this;**　を記載

　これで親ウィンドウをオーナーウィンドウとして設定する

2. **Show()**を使用して表示

　モーダレスダイアログではshowDialog()は使わないこと。 
以下サンプルコードの様に、モーダレスダイアログのオーナーウィンドウがどれかを設定し、**Show メソッド**を使用して表示します。

```C#:モーダレスダイアログの呼び出し
    void button_Click(object sender, EventArgs e)
    {
        Dialog1 dialog1 = new Dialog1();
        dialog1.Owner = this;  // オーナーウィンドウの設定。一番最初に起動するForm画面を親に設定
        dialog1.Show();        // モードレスダイアログとして表示
    }
```

#7. ダイアログ上のボタンイベント結果取得について

ダイアログ上のどのボタンが押されたのかという情報は、ShowDialogメソッドの返り値から知ることができるらしいっすよ。

どんな手順でボタン押下結果を取得するのかは以下参照。

　1. ダイアログ用クラスにボタン用イベントハンドラ関数を作成

```C#:ボタン用イベントハンドラ作成
// 自作メッセージボックス
class Dialog1 : Form
{
//(省略）
    public Dialog1()
    {
        //(省略）
        
        // Yesボタン用イベントハンドラ関数
        buttonYes = new Button()
        {
           //(省略）
        };
```

　2. ボタン用イベントハンドラ関数に、ダイアログの結果を追記

```C#:ボタン用イベントハンドラにボタン押下結果を追記
// 自作メッセージボックス
//(省略）
    public Dialog1()
    {
        //(省略）
        
        // Yesボタン用イベントハンドラ関数
        buttonYes = new Button()
        {
           //(省略）
           // ダイアログの結果を次に記載
           DialogResult = DialogResult.Yes,  //ダイアログの結果
        };
```

　3. フォーム画面用クラスで、DialoｇResult変数にダイアログ結果（ShowDialog()の返り値）を保存

```C#:フォーム画面用コード
class Form1 : Form
{
    public Form1()
    {
       // コンストラクタ処理
    }
    // フォームを閉じたときのイベントハンドラ関数
    void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        // ダイアログ生成
        Dialog1 dialog1 = new Dialog1();
        // ダイアログの結果保存用変数作成＆結果取得
        DialogResult result = dialog1.ShowDialog();
        // ダイアログ結果がYesじゃなければ、フォームを閉じない
        if (result != DialogResult.Yes)
        {
            e.Cancel = true;
        }
    }
}
```

これでダイアログ上のボタンでどれが押されたかが分かりますね！

#8. ダイアログ上のチェックボックスやテキストボックスの状態取得

ダイアログのデザイン画面でチェックボックスやテキストボックスを配置した場合、ダイアログ以外からは内容を取得できません。
これはデザイナー画面で配置した場合、すべてprivate設定になってしまう為です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2130837/8caa5772-5aa4-a58a-7268-43a301a0d1fe.png)

こんな感じにチェックボックス、テキストボックスを配置した場合、以下の様にprivate設定のInitializeComponent()関数で画面に配置されることになる。

```C#:(ダイアログ用ファイル名).Designer.csの内容
//(省略）

// デザイナ画面で配置した各要素は、以下InitializeComponent()で呼び出される。この関数がprivateなのが原因
private void InitializeComponent()
{
    this.YES = new System.Windows.Forms.Button();
    this.No = new System.Windows.Forms.Button();
    this.label1 = new System.Windows.Forms.Label();
    this.textBox1 = new System.Windows.Forms.TextBox();
    this.TopMostBox = new System.Windows.Forms.CheckBox();
    this.MaximizeChkBox = new System.Windows.Forms.CheckBox();
    this.MinimizeChkBox = new System.Windows.Forms.CheckBox();
    this.SuspendLayout();
    // 
    // YES
    // 
    this.YES.Font = new System.Drawing.Font("MS UI Gothic", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)));

// (省略）
```
##8.1 解決方法1：デザイナ画面ではなく、直接ソースコードを編集してチェックボックス等を配置する

参考サイトのやり方を真似ればOK。public設定で各要素を配置できるので、そのままForm画面からも参照可能となる

##8.2 解決方法2：各要素の内容を保存するためのpublic変数を用意し、その内容を参照する

　1. ダイアログ用クラス内に、publicのクラス変数を用意。そこに各要素の内容を保存する。

　2. Form用のForm1.csで " using (ダイアログ用クラスの名前空間）"を記載

　3.  (ダイアログ用クラス名).(各要素の内容を保存しているpublic変数名）で、チェックボックスやテキストボックスの内容を参照

```C#:DiagForm.cs
//(省略）
namespace DialogTest
{
    public partial class DiagForm : Form
    {
        public Boolean checkBoxResult1, checkBoxResult2, checkBoxResult3;
        public String textresult;

        public DiagForm()
        {
            InitializeComponent();
        }

        private void YES_Click(object sender, EventArgs e)
        {
            textresult      = this.textBox1.Text;
            checkBoxResult1 = this.TopMostBox.Checked;
            checkBoxResult2 = this.MaximizeChkBox.Checked;
            checkBoxResult3 = this.MinimizeChkBox.Checked;
            DialogResult    = DialogResult.Yes;
        }

        private void No_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.No;
        }
    }
}
```


```C#:Form1,cs
using DialogTest;
//(省略）

namespace  ProjectName
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            DiagForm diagForm = new DiagForm();
            // ダイアログのイベント結果を取得
            DialogResult dialogResult = diagForm.ShowDialog();
            // Yesボタンを押された場合
            if (dialogResult == DialogResult.Yes)
            {
                // ダイアログのテキストボックス内容を取得
                this.Text           = diagForm.textresult;
                // チェックボックス（一番上）の結果取得
                this.TopMost        = diagForm.checkBoxResult1;
                // チェックボックス（真ん中）の結果取得
                this.MaximizeBox    = diagForm.checkBoxResult2;
                // チェックボックス（一番下）の結果取得
                this.MinimizeBox    = diagForm.checkBoxResult3;
            }
        }
    }
}
```
##8.3 解決方法3：プロパティからpublicに変更
テキストボックスやチェックボックスのプロパティ内「Modifies」をprivateからpublicに変更することで、Form画面からも結果を参照できるようになります。

![プロパティ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2130837/bf70557f-2cc1-3be0-3959-68bb0260bf1f.png)

#9. 振り返り
面白かった（コナミ）
でももう少し進捗出したかったね

#10． 次回予告
オフで続き勉強しようと思ったけど時間なかった。次回はタブ付きページを学ぶよ。
第7回は11月14日(日）の夜8時から以下チャンネルで行います！

##ニコニコ配信先
https://com.nicovideo.jp/community/co3601066

##Twitch配信先
https://www.twitch.tv/programing_study_meeting

##Discordリンク
https://discord.gg/7rcqhMGpvA