画像のドラッグ&ドロップ(3)
コピーと移動の違い
先ほどの例では、PictureBoxコントロールから画像をコピーしたり移動したりする方法を紹介しました。通常の移動処理では、別のコントロールや別の場所に画像をコピーした後、元の画像を削除する必要があります。では、ドロップ操作が完了したタイミングを知るにはどうしたらいいのでしょうか。それにはQueryContinueDragイベントを使用します。
図9のように、Form1にPictureBoxコントロールをもう1つ追加します。これを使用して、PictureBox1からPictureBox2に画像をドラッグ&ドロップで移動するサンプルを作成していきます。

Form1_LoadイベントでPictureBox2を次のように設定します。
Private Sub Form1_Load( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load '---set the control to allow drop--- TextBox1.AllowDrop = True '---set the control to allow drop--- With PictureBox1 .AllowDrop = True .BorderStyle = BorderStyle.FixedSingle .SizeMode = PictureBoxSizeMode.StretchImage End With '---set the control to allow drop--- With PictureBox2 .AllowDrop = True .BorderStyle = BorderStyle.FixedSingle .SizeMode = PictureBoxSizeMode.StretchImage End With ...
ドロップをサポートするため、リスト1のコードをPictureBox2に追加します。
Private Sub PictureBox2_DragDrop( _ ByVal sender As Object, _ ByVal e As System.Windows.Forms. _ DragEventArgs) _ Handles PictureBox2.DragDrop '---if the data to be dropped is a bitmap format--- If (e.Data.GetDataPresent(DataFormats.Bitmap)) Then '---set the control to display ' the bitmap being dropped--- PictureBox2.Image = e.Data.GetData( _ DataFormats.Bitmap) End If '---set the borderstyle back to its original--- PictureBox2.BorderStyle = BorderStyle.FixedSingle End Sub Private Sub PictureBox2_DragEnter( _ ByVal sender As Object, _ ByVal e As System.Windows.Forms. _ DragEventArgs) _ Handles PictureBox2.DragEnter '---if the data to be dropped is an image format--- If (e.Data.GetDataPresent(DataFormats.Bitmap)) Then '---determine if this is a copy or move--- If (e.KeyState And CtrlMask) = CtrlMask Then e.Effect = DragDropEffects.Copy Else e.Effect = DragDropEffects.Move End If '---change the border style of the control--- PictureBox2.BorderStyle = BorderStyle.Fixed3D End If End Sub Private Sub PictureBox2_DragLeave( _ ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles PictureBox2.DragLeave '---set the borderstyle back to its original--- PictureBox2.BorderStyle = BorderStyle.FixedSingle End Sub
移動操作では、ユーザーがPictureBox2に画像を移動させた後、PictureBox1の画像を削除しなければなりません。この処理のために、PictureBox1のQueryContinueDragイベントにコードを記述する必要があります。このイベントは、PictureBox1から画像をドラッグ&ドロップした後に発生します。そのイベントコードの中で、行ったドラッグ操作が移動かどうかを判断し、移動である場合はPictureBox1から画像を削除します。
Private Sub PictureBox1_QueryContinueDrag( _ ByVal sender As Object, _ ByVal e As _ System.Windows.Forms.QueryContinueDragEventArgs) _ Handles PictureBox1.QueryContinueDrag If e.Action = DragAction.Drop Then If (e.KeyState And CtrlMask) <> CtrlMask Then '---a move operation--- PictureBox1.Image = Nothing End If End If End Sub
ここでコードをテストできます。Visual Studio 2005のF5キーを押して、PictureBox1に画像をドラッグ&ドロップします。次に、PictureBox1の中にある画像をドラッグして、PictureBox2にドロップします。ドロップ後、PictureBox1の中の画像がなくなることに注目してください。移動ではなくコピーを行った場合、つまりCtrlキーを押したままPictureBox1からPictureBox2まで画像をドラッグした場合は、QueryContinueDragイベントのコードでは画像をコピーするだけで、削除しません。
1つ注意してほしいのは、ユーザーが移動させたアイテムをQueryContinueDragイベントで削除するという手法は、フールプルーフな方法ではないという点です。移動操作が失敗した場合(PictureBox2の外に画像をドロップした場合など)でも、画像の削除が実行されてしまいます。QueryContinueDragイベントを使用する方法では、ユーザーがアイテムをどこに移動したか(またはドロップしたか)や、操作が失敗したかどうかは分かりません。
