データグリッドビューについて

タグの編集
投稿者 うさぎ  (学生) 投稿日時 2011/12/6 18:33:53
VB2005を勉強中のものです。
Form上に2つのDataGridViewががあり、DataGridView1からDataGridView2へ選択した行をドラッグアンドドロップしたいのですがマウスでドロップした場所(2行目や5行目)に行が移るにはどうしたらいいのでしょうか。
本などを参考にしたのですがいまのコードでは指定した場所に挿入されません。
よろしくお願いします。


MouseMoveのとこる
 If e.Button = MouseButtons.Left Then
        If NOt dragbox.contains(e.X, e.Y) then
Dim dropresult As DragDropEffects = DataGridView1.DoDragDrop(DataGridView1.CurrentRow.ragDropEffects.Move)
DataGridView2.Row.Add
DataGridView1.CurrentRow.Cells("Number").Value,("NAME").Value)
DataGridView1.Row.Remove(DataGridView1.CurrentRow)
    End If

End Sub
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/12/6 20:40:02
コードが長くなったので、二回に分けて書きます。

Partial Public Class Form1
    Inherits System.Windows.Forms.Form

#Region "デモ用コントロールの配置"

    Private panel As SplitContainer
    Private WithEvents dgv1 As DataGridView
    Private WithEvents dgv2 As DataGridView

    Private Sub Form1_Load(ByVal sender As ObjectByVal e As EventArgs) Handles MyBase.Load
        panel = New SplitContainer()
        panel.Orientation = Orientation.Horizontal
        panel.Dock = DockStyle.Fill
        Controls.Add(panel)

        dgv1 = New DataGridView()
        dgv1.Dock = DockStyle.Fill
        dgv1.AllowDrop = False

        dgv2 = New DataGridView()
        dgv2.Dock = DockStyle.Fill
        dgv2.AllowDrop = True

        panel.Panel1.Controls.Add(dgv1)
        panel.Panel2.Controls.Add(dgv2)

        dgv1.AllowUserToAddRows = False
        dgv1.ReadOnly = True
        dgv1.ColumnCount = 3
        dgv1.RowCount = 20
        dgv1.MultiSelect = False
        dgv1.SelectionMode = DataGridViewSelectionMode.FullRowSelect

        dgv2.AllowUserToAddRows = False
        dgv2.ReadOnly = True
        dgv2.ColumnCount = 3
        dgv2.RowCount = 10
        dgv2.MultiSelect = False
        dgv2.SelectionMode = DataGridViewSelectionMode.FullRowSelect

        For rowIndex As Integer = 0 To 19
            dgv1(0, rowIndex).Value = String.Format("{0}-0", rowIndex)
            dgv1(1, rowIndex).Value = String.Format("{0}-1", rowIndex)
            dgv1(2, rowIndex).Value = String.Format("{0}-2", rowIndex)
        Next
        For rowIndex As Integer = 0 To 9
            dgv2(0, rowIndex).Value = String.Format("{0}-A", rowIndex)
            dgv2(1, rowIndex).Value = String.Format("{0}-B", rowIndex)
            dgv2(2, rowIndex).Value = String.Format("{0}-C", rowIndex)
        Next
    End Sub
#End Region

End Class
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/12/6 20:41:05
ここからが本題。

Partial Public Class Form1
    Inherits System.Windows.Forms.Form

    Private dragBox As Rectangle

    Private Sub dgv1_MouseDown(ByVal sender As ObjectByVal e As MouseEventArgs) Handles dgv1.MouseDown
        Dim sz As Size = SystemInformation.DragSize
        dragBox = New Rectangle(e.X - sz.Width \ 2, e.Y - sz.Height \ 2, sz.Width, sz.Height)
    End Sub

    Private Sub dgv1_MouseUp(ByVal sender As ObjectByVal e As MouseEventArgs) Handles dgv1.MouseUp
        dragBox = Rectangle.Empty
    End Sub

    Private Sub dgv1_MouseMove(ByVal sender As ObjectByVal e As MouseEventArgs) Handles dgv1.MouseMove
        If e.Button = MouseButtons.Left AndAlso Not dragBox.IsEmpty AndAlso dragBox.Contains(e.X, e.Y) Then
            dragBox = Rectangle.Empty
            Dim ht As DataGridView.HitTestInfo = dgv1.HitTest(e.X, e.Y)
            If ht.RowIndex >= 0 Then
                Dim row As DataGridViewRow = dgv1.Rows(ht.RowIndex)
                Dim data As New ArrayList()
                For Each cell As DataGridViewCell In row.Cells
                    data.Add(cell.Value)
                Next

                'ここでは、コピーするデータを「配列」として渡している 
                Dim effect As DragDropEffects = dgv1.DoDragDrop( _
                    data.ToArray(), _
                    DragDropEffects.Copy Or DragDropEffects.Move)

                If CBool(effect And DragDropEffects.Move) Then
                    dgv1.Rows.Remove(row)   '移動が行われた場合は元データを削除する 
                End If
            End If
        End If
    End Sub

    'コピー/移動の切り替えが不要な場合は、DragOver イベントよりも DragEnter イベントの方が良いかも 
    Private Sub dgv2_DragOver(ByVal sender As ObjectByVal e As DragEventArgs) Handles dgv2.DragOver
        If Not e.Data.GetDataPresent(GetType(Object())) Then
            Return  '意図しないデータなので無視 
        End If

        'ドラッグ中に Ctrl キーが押された場合は、コピー動作として扱う 
        Dim isCopy As Boolean = CBool(e.AllowedEffect And DragDropEffects.Copy) AndAlso CBool(e.KeyState And &H8)
        Dim isMove As Boolean = Not isCopy AndAlso CBool(e.AllowedEffect And DragDropEffects.Move)
        If isCopy Then
            e.Effect = DragDropEffects.Copy
        ElseIf isMove Then
            e.Effect = DragDropEffects.Move
        Else
            Return
        End If

        'ドラッグ先を選択状態にして、どこにドロップされるのかが分かるようにする 
        dgv2.ClearSelection()
        Dim pt As Point = dgv2.PointToClient(New Point(e.X, e.Y))
        Dim ht As DataGridView.HitTestInfo = dgv2.HitTest(pt.X, pt.Y)
        If ht.RowIndex >= 0 Then
            'データ部のセルまたは行ヘッダ上にいる場合 
            dgv2.Rows(ht.RowIndex).Selected = True
        Else
            '領域外にいる場合はドロップ禁止 
            e.Effect = DragDropEffects.None
        End If
    End Sub

    'ドロップされる側の処理 
    Private Sub dgv2_DragDrop(ByVal sender As ObjectByVal e As DragEventArgs) Handles dgv2.DragDrop
        Dim data() As Object = e.Data.GetData(GetType(Object()))
        If data Is Nothing Then
            Return  '意図しないデータなので無視 
        End If

        Dim pt As Point = dgv2.PointToClient(New Point(e.X, e.Y))
        Dim ht As DataGridView.HitTestInfo = dgv2.HitTest(pt.X, pt.Y)
        dgv2.ClearSelection()

        'ドロップ先のひとつ上の行に挿入し、挿入した新規行を選択状態にする 
        '(一番下に追加したい場合にはどうする?) 
        Dim newRowIndex As Integer = ht.RowIndex
        dgv2.Rows.Insert(newRowIndex, data)
        dgv2.Rows(newRowIndex).Selected = True
    End Sub

End Class