- ベストアンサー
C#, listBoxのItem追加についての質問
- C#のlistBoxでアイテムを追加する方法について質問があります。
- 二つのリストボックスがあり、rightbuttonをクリックすると選択されたアイテムがlistBox2に移動します。
- 移動したアイテムをlistBox1に戻す際、元の位置に戻す方法が分かりません。お力添えいただけますでしょうか。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
listBox1に追加するオブジェクトに,本来の並び順を保持させておいて, 戻す時にはオブジェクトの並び順を見てInsertする位置を決めればよいでしょう。 ListBoxに追加できるのは文字列だけでなく,どんなオブジェクトでも追加できます。 また,要素の表示はListBoxのDisplayMemberで決定されますが,DisplayMemberを指定していない場合はToStringが使われます。 なので, class Item : IComparable<Item> { public Item (string display, int defaultOrder) { Display = display; DefaultOrder = defaultOrder; } public string Display { get; private set; } public int DefaultOrder { get; private set; } int IComparable<Item>.CompareTo (Item other) { if (other == null) { return 1; } return DefaultOrder.CompareTo(other.DefaultOrder); } public override string ToString () { return Display; } } というようなクラスを作り,このItemクラスをlistBox1, listBox2の要素としておけば, var pos = listBox1.Items.Cast<Item>().ToList().BinarySearch(addItem); if (pos < 0) { pos = ~pos; } listBox1.Items.Insert(pos, addItem); で戻すことができます。
その他の回答 (3)
- Wr5
- ベストアンサー率53% (2173/4061)
というワケで…簡単に作ってみました。 検証不十分と思われますので、地道に検証してくださいな。 ちなみに、プロパティでbutton1(rightbutton相当)とbutton2(lefghtbutton相当)のEnabledはfalseに、 listBox1のItemsにはあらかじめデータ入れておいてください。 あと、全角空白でインデントしていますのでよろしく処理してください。 コメントも特に入れていないので自力で読んでください。 public partial class Form1 : Form { private Stack<MoveItemHistory> History; public Form1() { InitializeComponent(); History = new Stack<MoveItemHistory>(); } private void button1_Click(object sender, EventArgs e) { MoveItemHistory temp = new MoveItemHistory(); temp.Index = listBox1.SelectedIndex; temp.ItemString = (string)listBox1.Items[temp.Index]; listBox2.Items.Add(temp.ItemString); listBox1.Items.RemoveAt(temp.Index); listBox1.SelectedIndex = -1; History.Push(temp); button2.Enabled = true; } private void button2_Click(object sender, EventArgs e) { MoveItemHistory temp = History.Pop(); button2.Enabled = (History.Count > 0); listBox2.Items.Remove(temp.ItemString); listBox1.Items.Insert(temp.Index, temp.ItemString); } private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { button1.Enabled = (listBox1.SelectedIndex != -1); } } public class MoveItemHistory { public int Index; public string ItemString; }
- Wr5
- ベストアンサー率53% (2173/4061)
>そうするとlistBox1の5番目[りんご] >をlistBox2に移動し、他のアイテムも複数移動したら >listBox1の配列のCountは(例えば)2つとかになりますよね。 >listBox2からlistBox1に戻すときに5番目、(移動するときに持っていたindex=5)にインサートしたら、配列範囲外になりませんか? だから、「最後の1つだけ…とか制限付くと思いますけども。」と書いたのですが……。 そういう制限なしでやりたいというのであれば、履歴を持ち続けるしかないでしょうね。 で、lefghtbuttonのたびに履歴から操作することに。 # 履歴を格納する構造体なり作って、List構造として記録…でしょうかねぇ。 # List<T>とかで。 # スタック構造でもいいのか…そういうのがあったかはちょっと不明ですが。 # 「C# アンドゥ 実装」辺りで検索するとよさげなものが見つかるかも知れませんね。
- Wr5
- ベストアンサー率53% (2173/4061)
>そこで質問です。 >そのときに2から1へ戻ったとき、普通にAdd()するのではなく、移動する前の状態の位置に戻したいのです。 ListBox.Items.Insert()ですかね。 最後の1つだけ…とか制限付くと思いますけども。 rightbuttonで移動(というかlistBox1から削除)する前にインデックスを記憶… lefghtbuttonで戻す時に記録していたインデックスを元にInsert() ってところでしょうかね。 listBox1の先頭のアイテムや最後のアイテムだった場合に正しく動作するか? というのはちゃんと確認してくださいな。
補足
listBox1の総数を5こだとします。 そうするとlistBox1の5番目[りんご] をlistBox2に移動し、他のアイテムも複数移動したら listBox1の配列のCountは(例えば)2つとかになりますよね。 listBox2からlistBox1に戻すときに5番目、(移動するときに持っていたindex=5)にインサートしたら、配列範囲外になりませんか? また、listbox1から2へいくつか移動した後から戻したとすると、 indexは混同しませんか? という感じで悩んでおります。。。 未熟者故、うまいロジックが思いつかないのです。 せっかく教えて下さったのですが、今一度お力添えをお願いいたします><