前回作成した自作フォトビューアー
これだとアプリを終了すると登録したファイルの情報もなくなってしまいます。そこで登録したファイルを保存できるようにしました。
登録したファイルを保存/読み出しできるようにする
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 |
public partial class Form1 : Form { private void toolStripButtonSave_Click(object sender, EventArgs e) { List<string> files = new List<string>(); foreach (string str in listBox1.Items) { files.Add(str); } if (saveFileDialog1.ShowDialog() == DialogResult.OK) { StreamWriter sw = new StreamWriter(saveFileDialog1.FileName, false, Encoding.UTF8); foreach (string str in files) { sw.WriteLine(str); } sw.Close(); } } private void toolStripButtonOpen_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK) { List<string> files = new List<string>(); StreamReader sr = new StreamReader(openFileDialog1.FileName); while (true) { string str = sr.ReadLine(); if (str == null) break; files.Add(str); } sr.Close(); listBox1.Items.Clear(); foreach (string str in files) { listBox1.Items.Add(str); } } } } |
項目の順番を入れ替える/コピーする
これで登録されたファイルを保存することができたのですが、順番を入れ替えることができるようにしたいと思いませんか?
えっ、思わない? 私は思います。なのでドラッグ&ドロップで登録されているファイルの順番を入れ替えることができるようにします。
そのためには、MouseDownを使います。ListBox.DoDragDropメソッドを呼ぶのですが、ドラッグが開始されたときにどの部分にマウスカーソルがあるか知る必要があります。
1 2 3 |
Point p = Control.MousePosition; p = listBox1.PointToClient(p);//ドラッグ開始時のマウスの位置をクライアント座標に変換 int index = listBox1.IndexFromPoint(p);//マウス下のListBoxのインデックスを得る |
とやれば、どの部分にマウスカーソルがあるかわかります。
DoDragDropメソッドには選択されているアイテムのIndexをわたしています。
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 |
public partial class Form1 : Form { public Form1() { // 他は前回と同じ。追加するのはこの2つ listBox1.MouseDown += ListBox1_MouseDown; listBox1.DragEnter += ListBox1_DragEnter; } private void ListBox1_MouseDown(object sender, MouseEventArgs e) { //マウス下のListBoxのインデックスを得る Point p = Control.MousePosition; p = listBox1.PointToClient(p); int index = listBox1.IndexFromPoint(p); if (index > -1) { listBox1.SelectedIndex = index; listBox1.DoDragDrop(index, DragDropEffects.All); //ドラッグスタート } } private void ListBox1_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(typeof(int))) { e.Effect = DragDropEffects.Move; } } } |
ドラッグされているのはint型データなのか、それともファイルなのか? GetDataPresentをつかえばわかります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public partial class Form1 : Form { private void listBox1_DragOver(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { e.Effect = DragDropEffects.Copy; } if(Control.ModifierKeys.HasFlag(Keys.Control)) e.Effect = DragDropEffects.Copy; else e.Effect = DragDropEffects.Move; } } |
ドロップされたらint型データを取得するとともに、ドロップされた場所を調べます。取得されたint型データとドロップされた場所がリストボックスの同じ項目であればなにもする必要はありません。
リストボックスのアイテムの順番を入れ替えるとき、選択されているアイテムが変更されます。そのときにListBox.SelectedIndexChangedイベントが発生するため、フィールド変数 isIgnoreを使ってなにも起きないようにしています。
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 |
public partial class Form1 : Form { bool isIgnore = false; private void listBox1_DragDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] vs = (string[])e.Data.GetData(DataFormats.FileDrop); Point point = listBox1.PointToClient(new Point(e.X, e.Y)); int index = listBox1.IndexFromPoint(point); if (index == -1) listBox1.Items.Add(vs[0]); else listBox1.Items.Insert(index, vs[0]); } if (e.Data.GetDataPresent(typeof(int))) { int i = (int)e.Data.GetData(typeof(int)); Point point = listBox1.PointToClient(new Point(e.X, e.Y)); int index = listBox1.IndexFromPoint(point); isIgnore = true; if (index == -1) { string str = (string)listBox1.Items[i]; if(e.Effect == DragDropEffects.Move) listBox1.Items.RemoveAt(i); listBox1.Items.Add(str); int count = listBox1.Items.Count; listBox1.SelectedIndex = count - 1; } else if (index < i) { string str = (string)listBox1.Items[i]; if (e.Effect == DragDropEffects.Move) listBox1.Items.RemoveAt(i); listBox1.Items.Insert(index, str); listBox1.SelectedIndex = index; } else if (index > i) { string str = (string)listBox1.Items[i]; if (e.Effect == DragDropEffects.Move) { listBox1.Items.RemoveAt(i); listBox1.Items.Insert(index - 1, str); listBox1.SelectedIndex = index - 1; } else if (e.Effect == DragDropEffects.Copy) { listBox1.Items.Insert(index, str); listBox1.SelectedIndex = index; } } string filePath = (string)listBox1.SelectedItem; ShowImage(filePath); isIgnore = false; } } private void ListBox1_SelectedIndexChanged(object sender, EventArgs e) { if (isIgnore) return; string filePath = (string)listBox1.SelectedItem; ShowImage(filePath); } } |
項目を削除する
並べ換えができるなら削除もできるはずです。やってみましょう。
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 |
public partial class Form1 : Form { private void toolStripButtonDelete_Click(object sender, EventArgs e) { int index = listBox1.SelectedIndex; if (index == -1) return; listBox1.Items.RemoveAt(index); int count = listBox1.Items.Count; if (count == 0) { Image image = pictureBox1.Image; pictureBox1.Image = null; image.Dispose(); return; } // 最後のアイテムが削除された場合 if (count == index) listBox1.SelectedIndex = index-1; // それ以外の場合 else listBox1.SelectedIndex = index; string filePath = (string)listBox1.SelectedItem; ShowImage(filePath); } } |