|
■No78099 (SVO さん) に返信
やりたいことがはっきりしているのだから、それをコードに翻訳すれば良いだけなんだけど。
Form1.button1 をクリックしたときに、Form2 を表示したい。
→
Form1 に Button を配置し、それを button1-1 と名付ける。
button1-1 のクリックイベントを書く。
void button1-1_clicked(object sender, EventArgs e)
{
Form2 を表示する
このフォームを消す→this.Hide(); // Close にすると、アプリケーションが終了する(はず)
}
ここで、「Form2 を表示する」をどうするか。単純には、こうする。
→
new Form2().Show();
これを続けると、Form4 で困る。
void button4-1_Click(object sender, EventArgs e)
{
Form3 を非表示にする
Form1 を表示する
this.Close();
}
ここで、Form1, Form3 が参照できない。
Form2 の様に「new Form1().Show();」とすると、Form4 から表示する Form1 は、最初に表示したものとは異なる。
同様の理由で、既にある Form3 を閉じることができない。
参照できないのは、参照できるところに置いていないから。
だったら、参照できるところに置けば良い。
方法はいくつかあり、単純な方法は、「教えてやる」こと。
→
class Form2
{
public Form ParentForm
{
get;
set;
}
}
としておいて、
void button1-1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ParentForm = this;
f2.Show();
this.Hide();
}
ただし、Form2 については、Form3 だけではなく、Form4 まで教えなければならない。
じゃぁ、Form4 には GrandParentForm プロパティを作るのか?
それは面倒くさい。
フォームを表示する順番が変わったり、表示非表示が変わったりしたら、変更量が大変なことになる。
参照できるところに、プログラム中に使用する Form の配列があったらどうか。
こんな風に書くことができる。
→
void button4-1_Click(object sender, EventArgs e)
{
formArray[2].Hide();
this.Close();
formArray[1].Show();
}
しかし、C# では、C/C++ のような、グローバル変数を宣言することはできない。
なので、Form の配列を提供するクラスを作って、そのインスタンスを1つに制限してやる。
インスタンスが複数あると、管理しているものとは違うリストを参照してしまうかもしれないからね。
→
class FormSore
{
// これが参照できるただ1つのインスタンス。
private static FormStore instance = new FormStore();
private List<Form> FormList
{
get;
private set;
}
// コンストラクタを private にして、他からインスタンスを作らせない。
private FormStore()
{
this.FormList = new List<Form>();
}
// ただ1つのインスタンスを参照するためのメソッド。
public static FormSotore GetInstance()
{
return FormStore.instance;
}
}
プログラムの開始時に、Form のインスタンスをこのリストに登録してやる。
→
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
FormStore sotore = FormStore.GetInstance();
store.FormList.Add(new Form1());
store.FormList.Add(new Form2());
store.FormList.Add(new Form3());
store.FormList.Add(new Form4());
Application.Run(store.FormList[0]);
}
これで、各ボタンの処理は、希望する処理のままに書ける。
void button1-1_Click(...)
{
this.Hide(); // Form1が消え
FormStore.GetInstance().FormList[1].Show(); // Form2が表示されます。
}
void button2-1_Click(...)
{
this.Hide(); // Form2が消え
FormStore.GetInstance().FormList[2].Show(); // Form3が表示されます。
}
void button3-1_Click(...)
{
FormStore.GetInstance().FormList[3].Show(); // Form4が表示されます。
}
void button4-1_Click(...)
{
this.Hide(); // Form4と
FormStore.GetInstance().FormList[2].Show(); // Form3が消え
FormStore.GetInstance().FormList[1].Show(); // Form2が表示されます。
}
これで、書かれていることは満足するのだけれど、終わりではない。
フォーム右上の×ボタンをクリックすると Close してしまう。
Show/Hide で制御したいので、勝手に「消去」されないように、「消去」時には「非表示」になるように変える。
→
// これを、Form1 以外に実装する。
public Form2()
{
InitializeComponent();
this.FormClosing += Form2_FormClosing;
}
void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
// ユーザーが閉じようとしたときに、「戻る」扱いとする。
// Form1 を表示して、
FormStore.GetInstance().FormList[0].Show();
// このフォームを「閉じる」イベントはキャンセルして、
e.Cancel;
// 非表示にする。
this.Hide();
}
}
|