解決となっていますが,方法が書かれていませんし,往々にしてまずい解決方法を採ることがあるので……。
・大きなプログラムで通常推奨される方法
Form2が必要とする情報や設定する情報をクラスにまとめ,そのクラスのインスタンスをForm1とForm2の間でやりとりする。
現実的にはModelに属するクラスを渡すことになるかと思います。
設定系などでキャンセル可能な場合は一度複製したものにデータを設定しておき,ApplyやOKのタイミングで複製したデータを有効化することになります。
コード:
class ProgramSettings
{
public ProgramSettings ()
{
Title = "";
}
public ProgramSettings (ProgramSettings other)
{
if (other == null) throw new ArgumentNullException(nameof other); // C# 6.0以降。C# 5.0かそれ以前ではnameofが使えないので"other"とする
this.Title = other.Title;
}
public string Title { get; set; } // やりとりする情報。とりあえずはひとつだけ。
}
コード:
public partial class Form2
{
private ProgramSettings _settings = new ProgramSettings();
public ProgramSettings Settings
{
get { return _settings; }
set
{
if (value == null) throw new ArgumentNullException(nameof Settings);
_settings = value;
}
}
protected override void OnLoad (EventArgs e)
{
base.OnLoad(e);
TextBox1.Text = _settings.Title;
}
private void TextBox1_TextChanged (object sender, EventArgs e)
{
_settings.Title = TextBox1.Text;
}
}
コード:
public partial class Form1
{
private ProgramSettings _settings; // どこかで代入済み
private void Button1_Click (object sender, EventArgs e)
{
using (var form2 = new Form2())
{
var temporarySettings = new ProgramSettings(_settings)
form2.Settings = temporarySettings ;
if (form2.ShowDialog(this) != DialogResult.OK) return;
_settings.Title = temporarySettings.Title; // 目的次第で_settings = temporarySettings;でもよい。
Label1.Text = _settings.Title;
}
}
}
・小さなプログラムで推奨される方法
個々のデータ毎にForm2にプロパティを作成します。
多くの情報を渡そうとすると設定項目が増えるため,あまりに増えた場合は先の方法の方がよいでしょう。
コード:
public partial class Form2
{
public string TitleSetting
{
get { return TextBox1.Text; }
set
{
if (value == null) throw new ArgumentNullException(nameof TitleSetting);
TextBox1.Text = value;
}
}
}
コード:
public partial class Form1
{
private void Button1_Click (object sender, EventArgs e)
{
using (var form2 = new Form2())
{
form2.TitleSetting = "" ;
if (form2.ShowDialog(this) != DialogResult.OK) return;
Label1.Text = form2.TitleSetting;
}
}
}
・ほとんど全ての場合において,推奨されない方法
Form2のTextBox1をinternalやpublicにして,Form1からアクセスを行う
コード:
public partial class Form1
{
private void Button1_Click (object sender, EventArgs e)
{
using (var form2 = new Form2())
{
form2.TextBox1.Text = "" ;
if (form2.ShowDialog(this) != DialogResult.OK) return;
Label1.Text = form2.TextBox1.Text;
}
}
}
この方法を使ってしまうと,例えばForm2の一部をユーザーコントロールとして切り出した場合などに,コードの修正がややこしくなります。
そもそも,他のクラスの内部実装をしらないと使えない時点でクラスとして失格です。