投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/9/9 20:45:37
ドロップされる側は、ドラッグ元がどのようにデータを管理しているかを知りません。
ドラッグする側は、ドロップ先がどのようにデータを表示しているのかを知りません。

なので、ドラッグ & ドロップの処理では、ドラッグ元ドロップ先のそれぞれが、
自身のデータのみを扱うべきであり、相手側を直接操作してはいけません。

刈谷勇さんが書かれているように、DoDragDrop の戻り値で判定してください。


Public Class Form1
    Private Sub Form1_Load(ByVal sender As ObjectByVal e As EventArgs) Handles MyBase.Load
        TextBox1.Text = "これはドラッグ元のテキストです。右ボタンでドラッグできます(Shiftで移動)。"
        TextBox1.Select(3, 5)
        TextBox1.AllowDrop = False
        TextBox2.Text = ""
        TextBox2.AllowDrop = True
    End Sub

    Private Sub TextBox2_DragOver(ByVal sender As Object, _
      ByVal e As DragEventArgs) Handles TextBox2.DragOver
        If e.Data.GetDataPresent(GetType(String)) Then
            'Shift キーが押されていれば移動扱い/押されていなければコピー 
            Dim IsShift As Boolean = CBool(ModifierKeys And Keys.Shift)
            If IsShift AndAlso CBool(e.AllowedEffect And DragDropEffects.Copy) Then
                e.Effect = DragDropEffects.Move
            ElseIf CBool(e.AllowedEffect And DragDropEffects.Copy) Then
                e.Effect = DragDropEffects.Copy
            End If
        End If
    End Sub

    Private Sub TextBox2_DragDrop(ByVal sender As Object, _
      ByVal e As DragEventArgs) Handles TextBox2.DragDrop
        TextBox2.Text = e.Data.GetData(GetType(String))
    End Sub

    Private downPos As Point = Point.Empty
    Private Sub TextBox1_MouseDown(ByVal sender As Object, _
      ByVal e As MouseEventArgs) Handles TextBox1.MouseDown
        'テキストの範囲選択と区別するために、 
        'ドラッグ & ドロップをマウス 右ボタンに割り当てる。 
        If CBool(e.Button And System.Windows.Forms.MouseButtons.Right) Then
            'ドラッグの開始位置 
            downPos = e.Location
        End If
    End Sub

    Private Sub TextBox1_MouseMove(ByVal sender As Object, _
      ByVal e As MouseEventArgs) Handles TextBox1.MouseMove
        If downPos.IsEmpty Then
            'ドラッグが開始されていない 
            Return
        End If

        'マウスの移動量がドラッグ開始量を越えているかを判定 
        Dim dragSize As Size = SystemInformation.DragSize
        Dim moveRect As New Rectangle( _
            downPos.X - dragSize.Width \ 2, _
            downPos.Y - dragSize.Height \ 2, _
            dragSize.Width, _
            dragSize.Height)
        If moveRect.Contains(e.Location) Then
            Return
        End If
        downPos = Point.Empty

        'コピーと移動を許可する 
        Dim effect As DragDropEffects
        effect = DragDropEffects.Copy Or DragDropEffects.Move

        '選択されたテキスト範囲をドラッグ 
        effect = TextBox1.DoDragDrop(TextBox1.SelectedText, effect)

        If CBool(effect And DragDropEffects.Move) Then
            '移動されたので選択範囲をクリアする 
            TextBox1.SelectedText = ""
        End If
    End Sub
End Class