C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: VS2008での複数のコンボボックス設定について


(過去ログ 118 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■69326 / inTopicNo.1)  VS2008での複数のコンボボックス設定について
  
□投稿者/ たろう (4回)-(2013/12/17(Tue) 10:31:15)

分類:[C#] 

visual studio 2008でのC#windowフォームアプリケーションを使ったプログラムを作成しています。

4つのコンボボックスA,B,C,DのIndexがそれぞれ 0=○、1=△、2=×であり
どれかのコンボボックスが○に変更された際他のコンボボックスが○の時は×に変更、△or×の時は変更なし。

というプログラムを作成したいです。
現在は

private void comboBoxA_SelectedIndexChanged(object sender, EventArgs e) {
  if (this.comboBoxA.SelectedIndex == 0) {
    if (this.comboBoxB.SelectedIndex == 0) {
      this.comboBoxB.SelectedIndex = 2;
    }
    if (this.comboBoxC.SelectedIndex == 0) {
      this.comboBoxC.SelectedIndex = 2;
    }
    if (this.comboBoxD.SelectedIndex == 0) {
      this.comboBoxD.SelectedIndex = 2;
    }
  }
}

といったようにコンボボックスの値が変更された際に他のコンボボックスを参照し○なら×に変更する、という処理をA,B,C,Dすべてのコンボボックスでやっています。
現状はこれで動いているのですが、コンボボックスが増えていく予定なのでこのまま一つ一つのボタンに設定していくのはミスがおきそうであり見直した際もわかりにくいものになってしまうのではないかと考えています。

1つのコンボボックスが変更された際に他の複数のコンボボックスを設定するような方法は上記以外にありませんでしょうか?
よろしくお願いします。

引用返信 編集キー/
■69327 / inTopicNo.2)  Re[1]: VS2008での複数のコンボボックス設定について
□投稿者/ 魔界の仮面弁士 (465回)-(2013/12/17(Tue) 10:57:14)
No69326 (たろう さん) に返信
> このまま一つ一つのボタンに設定していくのはミスがおきそうであり

これでどうでしょう。

private bool updating = false;
private List<ComboBox> comboBoxes = new List<ComboBox>();

private void Form1_Load(object sender, EventArgs e)
{
    comboBoxes.Add(comboBox1);
    comboBoxes.Add(comboBox2);
    comboBoxes.Add(comboBox3);
    comboBoxes.Add(comboBox4);

    updating = true;
    foreach (var combo in comboBoxes)
    {
        combo.DataSource = new string[] { "○", "△", "×" };
        combo.SelectedIndex = -1;
        combo.SelectedIndexChanged += comboBoxes_SelectedIndexChanged;
    }
    updating = false;
}

private void comboBoxes_SelectedIndexChanged(object sender, EventArgs e)
{
    if (updating) return; else updating = true;

    var c = (ComboBox)sender;
    if (c.SelectedIndex == 0)   // コンボボックスが○に変更された際
    {
        var q = comboBoxes.Except(new ComboBox[] { c })     // 他のコンボが
                .Where(x => x.SelectedIndex == 0);          // ○であれば
        foreach (var combo in q) combo.SelectedIndex = 2;   // ×に変更
    }

    updating = false;
}

引用返信 編集キー/
■69329 / inTopicNo.3)  Re[1]: VS2008での複数のコンボボックス設定について
□投稿者/ shu (454回)-(2013/12/17(Tue) 11:01:57)
No69326 (たろう さん) に返信

配列にして一括でイベントを設定すると良いかと思います。

public partial class Form1 : Form
{
	private ComboBox[] cmbs;

	public Form1()
	{
		InitializeComponent();
		cmbs= new ComboBox[] {comboBox1,comboBox2,comboBox3,comboBox4};
		foreach (var cmb in cmbs)
		{
			cmb.SelectedIndexChanged+= new EventHandler(cmb_SelectedIndexChanged);
		}
	}

	private void cmb_SelectedIndexChanged(object sender, EventArgs e)
	{
		if (((ComboBox)sender).SelectedIndex == 0)
		{
			foreach (var cmb in cmbs.Where((cmb2) => (cmb2 != sender) && (cmb2.SelectedIndex==0)))
			{
				cmb.SelectedIndex = 2;
			}
		}
	}
}

引用返信 編集キー/
■69330 / inTopicNo.4)  Re[2]: VS2008での複数のコンボボックス設定について
□投稿者/ shu (455回)-(2013/12/17(Tue) 11:18:38)
No69329 (shu さん) に返信

魔界の仮面弁士さんとかぶってしまいました。

私の方はイベント連鎖の回避用の処理を特に入れていませんが
今回のケースではSelectedIndex==0になる変更をしていないので
なくても大丈夫です。ただ一般的にはSelectedIndexによるSelectedIndexイベントの
発生を考慮して処理を入れる必要があります。
引用返信 編集キー/
■69336 / inTopicNo.5)  Re[2]: VS2008での複数のコンボボックス設定について
□投稿者/ たろう (6回)-(2013/12/17(Tue) 14:53:01)
魔界の仮面弁士さんshuさん回答ありがとうございます。
お二方の解答をもとに配列にして一括でイベントを設定することでcomoboboxの変更がうまくいきました。
shuさんのコードを元に変更を行ったのですがこのコードについて質問があるのでよければ解説してくれませんでしょうか?

> foreach (var cmb in cmbs.Where((cmb2) => (cmb2 != sender) && (cmb2.SelectedIndex==0)))

検索をしてラムダ式の構文を使っているということまではわかったのですがwhere以降が難しいです。
cmb2とsenderが何を意味するパラメータなのかがわかりません。
おそらく以前と現在のIndexを比べて変化してるかどうかを見ているのではないかとは思うのですが、よろしければどのパラメータが入ってくるのか教えていただけませんでしょうか?


引用返信 編集キー/
■69338 / inTopicNo.6)  Re[3]: VS2008での複数のコンボボックス設定について
□投稿者/ shu (456回)-(2013/12/17(Tue) 16:09:31)
No69336 (たろう さん) に返信
> 検索をしてラムダ式の構文を使っているということまではわかったのですがwhere以降が難しいです。
> cmb2とsenderが何を意味するパラメータなのかがわかりません。

senderはイベントの引数のsenderでSelectedIndexChangedが発生したコンボボックスになります。
cmbs.Where((cmb2) => 条件)
は
cmbsより1つづつ取出しその取出したコンボボックスを仮にcmb2とするといった意味合いになります。

List<ComboBox> cmbs2 = new List<ComboBox>();
foreach (var cmb2 in cmbs)
{
    if (〜 Whereの条件と同じ 〜)
    {
        cmbs2.Add(cmb2);
    }
}
を処理したcmbs2に近いものになります。

実際にはこの処理を行いながらcmbs2.Add(cmb2)のタイミングでcmb2をcmbに設定して前述の処理を行う
イメージです。

引用返信 編集キー/
■69342 / inTopicNo.7)  Re[4]: VS2008での複数のコンボボックス設定について
□投稿者/ たろう (8回)-(2013/12/17(Tue) 17:22:59)
No69338 (shu さん) に返信

> senderはイベントの引数のsenderでSelectedIndexChangedが発生したコンボボックスになります。
> cmbs.Where((cmb2) => 条件)
> は
> cmbsより1つづつ取出しその取出したコンボボックスを仮にcmb2とするといった意味合いになります。
>
> List<ComboBox> cmbs2 = new List<ComboBox>();
> foreach (var cmb2 in cmbs)
> {
> if (〜 Whereの条件と同じ 〜)
> {
> cmbs2.Add(cmb2);
> }
> }
> を処理したcmbs2に近いものになります。

説明ありがとうございました。
ラムダ式の構文は使った事なく困っていましたが理解できましたありがとうございます。
foreachとWhereについて学ぶことができたので今後に活かしていきたいと思います。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -