- - PR -
リストボックス内の項目をドラッグ&ドロップで移動させたい
1
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-05-25 19:01
リストボックス内の項目をドラッグ&ドロップで移動させたいのですが、うまく行きません。
1.リストボックス内の項目(複数)を選択する(Ctrl+マウス左クリック) 2.同じリストボックス内にドラッグ&ドロップする 3.ドロップした箇所に、選択した項目が移動する リストボックスに、以下のように実装しています。 listBox.MultiColumn = false; listBox.SelectionMode = SelectionMode.MultiExtended; listBox.MouseDown += new MouseEventHandler(listBox_MouseDown); listBox.DragEnter += new DragEventHandler(listBox_DragEnter); listBox.DragDrop += new DragEventHandler(listBox_DragDrop); そして、文末のようにイベント処理を実装しています。 ドラッグ&ドロップすると、 ・あらぬところに移動する ・移動しない という現象になります。 ★印のあたりが怪しいと思っています。 Webサイトを検索しながら、ここまで見様見真似で書いてきました。 デバッグして下さる方がいれば、是非お願いします。 参考になるサイトのご教示でも結構です。宜しくお願いします。 private void listBox_MouseDown(object sender, MouseEventArgs e) { //マウスの左ボタンだけが押されている時のみドラッグできるようにする if(e.Button == MouseButtons.Left) { //ドラッグの準備 ListBox lbx = (ListBox)sender; //ドラッグするアイテムのインデックスを取得する int itemIndex = lbx.IndexFromPoint(e.X, e.Y); if(itemIndex < 0) return; //ドラッグするアイテムの内容を取得する string itemText = (string)lbx.Items[itemIndex]; //ドラッグ&ドロップ処理を開始する DragDropEffects dde = lbx.DoDragDrop(itemText, DragDropEffects.All); //ドロップ効果がMoveの時はもとのアイテムを削除する if(dde == DragDropEffects.Move) lbx.Items.RemoveAt(itemIndex); } } private void listBox_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) { if(e.Data.GetDataPresent(DataFormats.FileDrop)) { e.Effect = DragDropEffects.All; } else if(e.Data.GetDataPresent(typeof(string))) { e.Effect = DragDropEffects.Move; //★ リストボックス内の移動だと、stringが入ってくる } else { e.Effect = DragDropEffects.None; } } private void listBox_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) { if(e.Data.GetDataPresent(typeof(string))) { ListBox lbx = (ListBox)sender; int itemIndex = lbx.IndexFromPoint(e.X, e.Y); //★ ここの戻り値が、-1だったり想定より大きい値だったりする string itemText = (string)e.Data.GetData(typeof(string)); this.listBox.Items.Insert(itemIndex, itemText); } else { string[] s = (string[])e.Data.GetData(DataFormats.FileDrop, false); for(int i = 0; i < s.Length; i++) { this.listBox.Items.Add(s[i]); } } } | ||||||||||||
|
投稿日時: 2006-05-25 19:33
DragEventArgsのYとかXで取得できるのは画面座標みたいですよ。
DragEventArgs メンバ | ||||||||||||
|
投稿日時: 2006-05-25 20:00
宇宙仮面さんとか、どぼんさんのところに、そのものがありますよ。
| ||||||||||||
|
投稿日時: 2006-05-25 20:03
早速の返信、ありがとうございます。 DragEventArgs は、私が記述したソースの「listBox_MouseDown」メソッドの中でも使っています。 このメソッドはドラッグ元の項目を処理しているのですが、 たとえばテキストエディタの上にドロップすると、テキストエディタには、 選択した項目がコピーされます。 ということは、DragEventArgsを使って座標軸から選択項目を判定させるのは、 うまくいっているような気がします。。。 気がするだけですが。 もしかすると、ドラッグ「先」のListBoxコントロールがうまく指定できていないのかなー | ||||||||||||
|
投稿日時: 2006-05-25 20:28
>private void listBox_MouseDown(object sender, MouseEventArgs e) { MouseEventArgsの場合は画面座標ではないようです。確かに画面座標とは書いてないですね。 MouseEventArgs メンバ
IndexFromPointはリストボックス内の座標を指定するもので、 DragEventArgsのYとかXは、リストボックス内の座標を返すものではない、ということです。
| ||||||||||||
|
投稿日時: 2006-05-25 20:35
まさに、どぼんさんのところのソースを参考に作ったんです! が、どぼんさんのソースは、ドロップ先リストボックスの「最後尾に」 項目を追加する例のため、今回の問題が解決できていません。 デバッガで確認したのですが、ドロップ先の位置を取得する int itemIndex = listBox.IndexFromPoint(e.X, e.Y); の戻り値がおかしいのが、今回の不具合のすべてです。 どうやったら、ドロップ「先」の位置(ListBox[x] だとすると、 xの値)を 取得できるのでしょうか。 | ||||||||||||
|
投稿日時: 2006-05-25 21:34
[quote]
べるさんの書き込み (2006-05-25 20:28) より:
>private void listBox_MouseDown(object sender, MouseEventArgs e) { MouseEventArgsの場合は画面座標ではないようです。確かに画面座標とは書いてないですね。 MouseEventArgs メンバ 鋭いご指摘、ありがとうございました! 仰る通り、 DragEventArgsで取得できる座標:画面左上からのマウス位置 MouseEventArgsで取得できる座標:コントロール左上からのマウス位置 なので、以下のように、コントロール左上からの位置を計算してあげたらうまくいきました! private void listBox_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) { if(e.Data.GetDataPresent(typeof(string))) { string itemText = (string)e.Data.GetData(typeof(string)); int toX = e.X - listBox.Location.X - panelConf.Location.X - this.Left; int toY = e.Y - listBox.Location.Y - panelConf.Location.Y - this.Top; |
1