以前にドラッグ&ドロップで項目の順序を変更できるリストボックスを作成しました。
今回はファイルとしてデータを保存できるリストボックスを作成します。
ListViewコントロールだと
1 2 3 |
ListViewItem item = new ListViewItem("新しいアイテム"); listView1.Items.Add(item); item.Tag = ここにデータをセットする |
というやり方もできるのですが、ListBoxの場合はそうはいかないので別にデータを扱う方法を考えます。
簡単な説明
Dataというクラスを作成し、そのインスタンスをリストに格納します。ただListBoxに普通にアイテムを追加してしまうとこの方法はとれないのでアイテムを追加するための方法に制限をかけます。
ユーザーコントロールを作成してこのなかにListBoxを入れます。これだと外部からは指定されたメソッドを使わないとアイテムを追加することができなくなります。
作成するクラスはSerializableListBox<T>とします。TはDataクラスを継承しているクラスでないといけません。
またSerializableListBox
使用できるメソッド
void AddItem(T data)
アイテムを最後に追加します。
void InsertItem(T data, int index)
アイテムを指定した場所に追加します。
void RemoveItem(int index)
指定した場所にあるアイテムを削除します。
void ClearItems()
アイテムをすべて削除します。
void MoveItem(int fromIndex, int toIndex)
第一引数で指定されたアイテムを第二引数で指定した場所に移動します。
void MoveItemLast(int fromIndex)
第一引数で指定されたアイテムを最後に移動します。
T GetData(int i)
第一引数で指定された場所にあるデータを取得します。
List<T> GetDataList()
シリアル化のためにデータのリストを取得します。
void SetDataList(List<T> dataList)
逆シリアル化で得られたデータのリストからリストボックスのアイテムを復元します。
virtual void OnDragOverItem(DragDropItemArgs e)
アイテムがドラッグオーバーされているときに呼び出されます。
virtual void OnDragOverObject(DragEventArgs e)
なにかがドラッグオーバーされているときに呼び出されます。
virtual void OnDragDropItem(DragDropItemArgs e)
アイテムがドロップされたときに呼び出されます。
virtual void OnDragDropObject(DragEventArgs e)
なにかがドロップされたときに呼び出されます。
virtual void OnSelectedIndexChanged(SelectedIndexChangedArgs e)
選択されているアイテムが変更されたときに呼び出されます。
プロパティ
bool AllowDrop
ドラッグ&ドロップを許可するかどうかを設定します。
int SelectedItemIndex
選択されているアイテムのインデックスを取得・設定します。
イベント
DragOverItem
アイテムがドラッグオーバーされているときに発生するイベントです。
DragOverObject
何かががドラッグオーバーされているときに発生するイベントです。
DragDropItem
アイテムがドロップされたときに発生するイベントです。
DragDropObject
何かががドロップされたときに発生するイベントです。
SelectedIndexChanged
選択されているアイテムが変更されたときに発生するイベントです。
ソースコードは次回示します。
使い方の一例
仕様
[追加]ボタンを押すと一番後ろに新しいアイテムが作成されます。
ドラッグ&ドロップでアイテムを移動できます。
選択されているアイテムが変更されるとこれまで選択されていたアイテムに対応するデータが保存され、新たに選択されたアイテムに対応するデータが読み出されて表示されます。
ファイルの保存と読み出しが可能です。
まずデータを扱うクラスを作成します。このクラスはDataクラスを継承している必要があります。Dataクラスの内容は次回示します。
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
namespace WindowsFormsApp1 { public class DataEx : Data { public string Text2 { get; set; } public string Text3 { get; set; } } } |
次にSerializableListBox
1 2 3 4 5 6 7 8 9 10 |
namespace WindowsFormsApp1 { public class SerializableListBoxData : SerializableListBox<DataEx> { public SerializableListBoxData() { } } } |
最後にForm1クラスを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void buttonAdd_Click(object sender, EventArgs e) { DataEx data = new DataEx(); data.Text = "名無しさん"; serializableListBoxData1.AddItem(data); } private void serializableListBoxData1_DragOverItem(object sender, SerializableListBoxData.DragDropItemArgs e) { if(e.SourceItemIndex != e.TargetItemIndex) e.Effect = DragDropEffects.Move; } private void serializableListBoxData1_DragDropItem(object sender, SerializableListBoxData.DragDropItemArgs e) { if(e.SourceItemIndex != e.TargetItemIndex) { serializableListBoxData1.MoveItem(e.SourceItemIndex, e.TargetItemIndex); } } private void serializableListBoxData1_SelectedIndexChanged(object sender, SerializableListBoxData.SelectedIndexChangedArgs e) { int before = e.BeforeSelectIndex; int after = e.AfterSelectIndex; if(before != -1) { serializableListBoxData1.GetData(before).Text = textBox1.Text; serializableListBoxData1.GetData(before).Text2 = textBox2.Text; serializableListBoxData1.GetData(before).Text3 = textBox3.Text; } if(after != -1) { textBox1.Text = serializableListBoxData1.GetData(after).Text; textBox2.Text = serializableListBoxData1.GetData(after).Text2; textBox3.Text = serializableListBoxData1.GetData(after).Text3; } } private void textBox1_TextChanged(object sender, EventArgs e) { int i = serializableListBoxData1.SelectedItemIndex; if(i != -1) serializableListBoxData1.GetData(i).Text = textBox1.Text; } public class Doc { public List<DataEx> datas = null; } private void buttonSaveFile_Click(object sender, EventArgs e) { SaveFileDialog dlg = new SaveFileDialog(); if(dlg.ShowDialog() == DialogResult.OK) { int i = serializableListBoxData1.SelectedItemIndex; if(i != -1) { serializableListBoxData1.GetData(i).Text = textBox1.Text; serializableListBoxData1.GetData(i).Text2 = textBox2.Text; serializableListBoxData1.GetData(i).Text3 = textBox3.Text; } Doc doc = new Doc(); doc.datas = serializableListBoxData1.GetDataList(); XmlSerializer xml = new XmlSerializer(typeof(Doc)); StreamWriter sw = new StreamWriter(dlg.FileName); xml.Serialize(sw, doc); sw.Close(); } } private void buttonLoadFile_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); if(dlg.ShowDialog() == DialogResult.OK) { XmlSerializer xml = new XmlSerializer(typeof(Doc)); StreamReader sr = new StreamReader(dlg.FileName); Doc doc = (Doc)xml.Deserialize(sr); sr.Close(); serializableListBoxData1.SetDataList(doc.datas); } } } } |