DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ListBoxで複数選択時のValueの取得

環境/言語:[C# VS2005 WindowsXp]
分類:[.NET]

いつもありがとうございます。
以下について教えてください。

C# VS2005 WindowsXpで開発しています。

ListBoxを2つ用意し複数選択して相互にデータを移す処理を行っています。
もとのデータはDBから取得するのですがデータバインドすると編集できないため、初期表示時にDBから取得したデータを一旦ArrayListにいれ、それをListBoxにAddRangeしています。
ArrayListにはKeyとValueをもたせ、ListBoxへの表示はValueのみです。

listBox1(対応データはarrayList1)
listBox2(対応データはarrayList2)


最終的にデータの移動を行った後の結果を保存したいのでListBoxでのやりとりのつどArrayListにも反映する必要があるかと思っていますが表示しているValueは問題ないもののKeyがうまく取得できません。

具体的には以下のようにしています

まず呼び出し時に以下の処理をしています(ArrayListにデータ取得)

// 全リストを最初に取得してArrayList1にSet
dsList.Clear();
oda.Fill(dsList);

this.listBox1.ValueMember = "Key";
this.listBox1.DisplayMember = "Value";

for (int i = 0; i < int.Parse(dsList.Tables["tbl"].Rows.Count.ToString()); i++)
{
arrayList1.Add(new System.Collections.DictionaryEntry(dsList.Tables["tbl"].Rows[i]["KeyCode"], dsList.Tables["tbl"].Rows[i]["Name"]));
}
// listbox1に1件ずつ追加
this.listBox1.Items.AddRange(arrayList1.ToArray());

this.listBox2.ValueMember = "Key";
this.listBox2.DisplayMember = "Value";



// データ移動時の処理は以下です。
private void btnAdd_Click(object sender, EventArgs e)
{
if (listBox1.SelectedItems.Count > 0)
{
int cnt = listBox1.SelectedItems.Count;
for (int i = 0; i < cnt; i++)
{
listBox2.Items.Add(listBox1.SelectedItems[i]);
// ここに arrayList2に上記のdataのAddが必要だと思っています。
}
for (int i = 0; i < cnt; i++)
{
listBox1.Items.Remove(listBox1.SelectedItems[0]);
allList1.RemoveAt(i);
}
listBox1.SelectedItems.Clear();
}

}
 
上記のコードにコメントをいれているのですが、selectedvalueがとれないのでどうしていいかわかりません。
どのようにしたらよいでしょうか?
なにとぞお教え願えませんでしょうか。
SelectedValueはValueMemberで指定したメンバのプロパティの値です。
DictionaryEntry自体をを移す必要があるのではないですか?

というわけで
SelectedIndicesで選択されたアイテムのインデックスを基にItem(n)をDictionaryEntryにキャストすればよいと思います。

以下、気になるところ。

DictionaryEntryはIDictionaryの要素として用意されています。
使っちゃいけないわけではないですが、構造体というのもちょっぴり気になりますし、2値しか保持できないというのもあります。
専用のデータクラスを用意してはどうでしょうか。
プロパティを必要な分実装できますし。

また、VS2005ということなので、Generic名前空間の使用をお勧めします。
書かれたソースでは、KeyValuePairとList<T>が対応します。
この場合もKeyValuePairではなく専用クラスのほうがよいでしょう。
http://msdn2.microsoft.com/ja-jp/library/6sh2ey19.aspx

最後に別の考え方をひとつ。

移動の際に基データであるArrayListも移動しようとしています。
もしリストボックスの各アイテムがどっちのArrayListのどの要素かを持てば、同時に移動する必要が無くなり元の形を維持できます。
これはいつでも、つまり移動するタイミングを最後まで引き伸ばせることを意味します。
これの利点の一つとして並べ替え専用サブフォームが考えられます。
並べ替えの元データを受け取り結果を返す仕様の場合、キャンセルされた際に元に戻すはおろか何もする必要がありません。
またリストボックスは見た目としての移動に専念できます
まどかさん。ありがとうございます。

具体的にどうやっていいかわからず、同じようなことをやっているサンプルをネットで探して、そのソースを修正して使ってしまったので、正直なところDictionaryEntryにこだわって使っているわけではないのです。

> 以下、気になるところ。
>
> DictionaryEntryはIDictionaryの要素として用意されています。
> 使っちゃいけないわけではないですが、構造体というのもちょっぴり気になりますし、2値しか保持できないというのもあります。
> 専用のデータクラスを用意してはどうでしょうか。
> プロパティを必要な分実装できますし。
>
> また、VS2005ということなので、Generic名前空間の使用をお勧めします。
> 書かれたソースでは、KeyValuePairとList<T>が対応します。
> この場合もKeyValuePairではなく専用クラスのほうがよいでしょう。
> http://msdn2.microsoft.com/ja-jp/library/6sh2ey19.aspx
>
> 最後に別の考え方をひとつ。
>
> 移動の際に基データであるArrayListも移動しようとしています。
> もしリストボックスの各アイテムがどっちのArrayListのどの要素かを持てば、同時に移動する必要が無くなり元の形を維持できます。
> これはいつでも、つまり移動するタイミングを最後まで引き伸ばせることを意味します。
> これの利点の一つとして並べ替え専用サブフォームが考えられます。
> 並べ替えの元データを受け取り結果を返す仕様の場合、キャンセルされた際に元に戻すはおろか何もする必要がありません。
> またリストボックスは見た目としての移動に専念できます
>

このあたりについても、まだまだ調べてみます。
共通データから必要なものを抜き出して個別データとして保存(共通は変更なし)。または、個別データから一部削除等を視覚的に実現するために上記のようなことをやりたいと思っています。
ですので双方にやりとりをするイメージではあるのですが、実際は最終的な動作として「ListBox2の一覧を個別データとして保存する」ことができればいいので、元データを残す必要はないと思っています。
保存の契機は保存ボタン押下です。

もう1日なんとかがんばってみて、またお伺いすると思いますのでよろしくお願いします。
ArrayListは編集せずに、listboxにtextのみではなくItemをそのまま追加することでデータ操作後もKeyとValueが取得できることがわかりました。
ですので、ArrayListは最初にListBoxにアイテムを追加するときのみ使用する形になりました。

これ以降の動作についても不明点があるのですが、タイトルの件は解決したので解決済みとし、新たにトピックを立てたいと思います。

ありがとうございました。
解決済みのチェックを忘れておりました。

次の質問も引き続きご享受いただけますようお願いします。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板