|
■No88561 (Dulu さん) に返信
>>やり方は何通りか思いつきますが、とりあえず 3 パターンほど書いてみると:
> 何通りかあるんですね…どれがいいのでしょう?
> どれもちんぷんかんぷんです。
提示頂いたコードだと、2 番に相当しますね。
実際には、「public Form1 Form1Instance;」は private の方が良いですけど。
> pictureBox1.Image = Properties.Resources.Default_Symbol.png
Properties.Resources.Default_Symbol.png は変ですね。
Properties.Resources.Default_Symbol_png もしくは
Properties.Resources.Default_Symbol なのではありませんか?
> public Form2(Form1 Form1Instance)
この場合 Form2 は、Form1 からしか呼び出せないことになりますので、
別の画面の選択でも使いたいといった使いまわしができなくなります。
(もちろん、Form2 が Form1 専用のクラスという位置づけならそれもアリですが)
もし、他のフォームからでも再利用できるようにしたいなら、
共通の interface を用意して、それを受け渡すようにすると良いでしょう。
> ネット検索を駆使して背景カラー(動いてるけど自信無い)だけは出来たんですが、
先の案1 の実装例。
// --------------------------------------------------------------
// 呼び出される側(選択画面)となる Form2。
// RadioButton を 6 つ貼っておきます。
public sealed partial class Form2 : Form
{
// 独自に作成した変更通知イベントです。
// 選択されている番号が変更された時に通知されます。
public event EventHandler<SelectedIndexEventArgs> SelectedIndexChanged;
// ラジオボタンは配列で管理しておくと便利です。
private RadioButton[] radioButtons = { };
public Form2(int initialIndex = 0)
{
InitializeComponent();
// InitializeComponent の呼び出しが終わったら、
// 6 つのラジオボタンを配列としてセットしておきます。
radioButtons = new RadioButton[6]
{
radioButton1,
radioButton2,
radioButton3,
radioButton4,
radioButton5,
radioButton6,
};
// 下記の行は、6 つすべてに、同じイベントハンドラを割り当てる処理です。
Array.ForEach(radioButtons, r => r.CheckedChanged += radioButtons_CheckedChanged);
// 上記の行では、CheckedChanged イベントをコードで割り当てていますが、
// あらかじめフォームのデザイン時に、radioButton1〜6 すべてに対して
// 一つのイベントハンドラ(radioButtons_CheckedChanged)を
// 手動で割り当てておいても OK です。
// 引数で示された選択肢を、最初に選んでおきます。
radioButtons[initialIndex].Checked = true;
// 今回のサンプルでは initialIndex 引数は指定していないので、
// 常に 0 番目である radioButton1 が選択状態になります。
}
// 6 つのラジオボタンすべてを、この一つの共通イベントで処理しています。
private void radioButtons_CheckedChanged(object sender, EventArgs e)
{
// 選択されたラジオボタンの番号を、0〜5 の値に変換します。
int index = Array.IndexOf(radioButtons, sender);
// 独自に用意した変更通知イベントを発生させます。
SelectedIndexChanged?.Invoke(this, new SelectedIndexEventArgs(index));
}
// これは、変更通知イベント用の EventArgs 継承クラスです。
// int 型を返すプロパティが用意されています。
public class SelectedIndexEventArgs : EventArgs
{
public int SelectedIndex { get; }
public SelectedIndexEventArgs(int selectedIndex)
{
SelectedIndex = selectedIndex;
}
}
}
// --------------------------------------------------------------
// 呼び出し元(メイン画面)となる Form1。
// 選択画面を呼ぶための Button を 2 つと、
// 画像表示用の PictureBox を 1 つ貼っておきます。
public partial class Form1 : Form
{
private Image[] images;
public Form1()
{
InitializeComponent();
// 6 種の画像をあらかじめ配列に入れておきます。
images = new Image[]
{
Properties.Resources.Default_Symbol,
Properties.Resources.Sun_Symbol,
Properties.Resources.Water_Symbol,
Properties.Resources.Fire_Symbol,
Properties.Resources.Forest_Symbol,
Properties.Resources.Skull_Symbol,
};
// 上記では、画像リソースごとに個別のプロパティ名で
// 取り出していますが、名前指定(string)で取得する方法もあります。
// https://dobon.net/vb/dotnet/programing/resourcemanager.html
// とりあえず、最初の画像を表示しておきます。
pictureBox1.Image = images[0];
}
// 六択画面(Form2)でラジオボタンの選択が変更されると、
// このイベントプロシージャが呼び出されます。
private void childForm_SelectedIndexChanged(object sender, Form2.SelectedIndexEventArgs e)
{
// 選択されたラジオボタンの番号に該当する画像に変更します。
pictureBox1.Image = images[e.SelectedIndex];
}
// 六択画面を「モーダル」で呼び出す場合はこのようにします。
private void button1_Click(object sender, EventArgs e)
{
using (var childForm = new Form2())
{
childForm.SelectedIndexChanged += childForm_SelectedIndexChanged;
childForm.ShowDialog(this);
}
}
// 六択画面を「モードレス」で呼びたい場合はこう。
private void button2_Click(object sender, EventArgs e)
{
button2.Enabled = false; // ボタンを使用不可にして二重呼び出しを防ぐ
childForm = new Form2();
childForm.SelectedIndexChanged += childForm_SelectedIndexChanged;
childForm.Show(this);
// 選択画面が閉じられたら、ボタンの状態を戻す
childForm.FormClosed += delegate { button2.Enabled = true; childForm = null; };
}
private Form2 childForm = null;
}
|