Form
の画面レイアウトが一杯になってきて設定画面を切り離したいときとかに、子ウィンドウを出したくなると思います。
今回はモーダルウィンドウ(閉じるまで親のForm
を操作できない)を表示させます。
モーダルウィンドウ モードレスウィンドウ - Google検索
画面キャプチャ
サンプルソースコード
using System;
using System.Drawing;
using System.Windows.Forms;
class MainForm : Form
{
MainForm()
{
Text = "Main window";
ClientSize = new Size(400,300);
var btn = new Button(){
Size = new Size(200,50),
Text = "Show sub window.",
};
Controls.Add(btn);
btn.Click += (s,e)=>{ ShowSubFormWithText("this is a sample."); };
}
static void ShowSubFormWithText(string text)
{
SubForm f = new SubForm(text);
f.ShowDialog();
}
[STAThread]
static void Main(string[] args)
{
Application.Run(new MainForm());
}
}
class SubForm : Form
{
public SubForm(string text)
{
Text = "Sub window";
ClientSize = new Size(300,150);
StartPosition = FormStartPosition.CenterParent;
// StartPosition = FormStartPosition.CenterScreen;
var txt = new TextBox(){
Text = text,
Multiline = true,
ScrollBars = ScrollBars.Both,
Dock = DockStyle.Fill
};
txt.KeyDown += (sender,e)=>{
if (e.Control && e.KeyCode == Keys.A) { txt.SelectAll(); }
};
Controls.Add(txt);
}
}
サブウィンドウから結果データを受け取りたい場合
参考サイト2を参考に作成しました。
using System;
using System.Drawing;
using System.Windows.Forms;
class MainForm : Form
{
MainForm()
{
Text = "Main window";
ClientSize = new Size(400,300);
var btn = new Button(){
Size = new Size(200,50),
Text = "Show sub window.",
};
Controls.Add(btn);
btn.Click += (s,e)=>{ ShowSubFormWithText("this is a sample."); };
}
static void ShowSubFormWithText(string text)
{
SubForm f = new SubForm(text);
DialogResult res = f.ShowDialog();
Console.WriteLine(res); // DialogResultの確認用
Console.WriteLine(f.Value); // 結果データの確認用
if ( res == DialogResult.OK ) {
// ... OKが押されたときの処理
}
}
[STAThread]
static void Main(string[] args)
{
Application.Run(new MainForm());
}
}
class SubForm : Form
{
public string Value;
TextBox txt;
public SubForm(string text)
{
Value = "";
Text = "Sub window";
ClientSize = new Size(300,200);
StartPosition = FormStartPosition.CenterParent;
// FormBorderStyle = FormBorderStyle.FixedSingle; // サイズ変更不可にする場合
txt = new TextBox(){
Location =new Point(0, 0),
Size = new Size(300, 160),
Text = text,
Multiline = true,
ScrollBars = ScrollBars.Both,
};
txt.KeyDown += (s,e)=>{
if (e.Control && e.KeyCode == Keys.A) { txt.SelectAll(); }
};
Controls.Add(txt);
var btn1 = new Button(){
Location =new Point(0, 160),
Size = new Size(150, 40),
Text = "OK",
};
var btn2 = new Button(){
Location =new Point(150, 160),
Size = new Size(150, 40),
Text = "Cancel",
};
btn1.Click += (s,e)=>{
DialogResult = DialogResult.OK;
Close();
};
btn2.Click += (s,e)=>{
DialogResult = DialogResult.Cancel;
Close();
};
Controls.Add(btn1);
Controls.Add(btn2);
FormClosed += (s,e)=>{Value = txt.Text;}; // SubFormが閉じられたときにデータをセットしておく
}
}
サブウィンドウf
が閉じて(FormClosed
)からも、f
を参照している限りはガベージコレクションの対象にはならないので、f
のフィールドValue
を取得することができる1。
という理屈のはず。
参考サイト
-
直接フィールドを参照するのはキモチワルイ気がするが、できるだけシンプルなサンプルになるようにフィールドを使用した。 ↩