Respuesta

5

Aquí es una versión VB de este C# Respuesta: How could I Drag and Drop DataGridView Rows under each other?

Las variables de clase formulario:

Private fromIndex As Integer 
Private dragIndex As Integer 
Private dragRect As Rectangle 

Los eventos de arrastre:

Private Sub DataGridView1_DragDrop(ByVal sender As Object, _ 
            ByVal e As DragEventArgs) _ 
            Handles DataGridView1.DragDrop 
    Dim p As Point = DataGridView1.PointToClient(New Point(e.X, e.Y)) 
    dragIndex = DataGridView1.HitTest(p.X, p.Y).RowIndex 
    If (e.Effect = DragDropEffects.Move) Then 
    Dim dragRow As DataGridViewRow = e.Data.GetData(GetType(DataGridViewRow)) 
    DataGridView1.Rows.RemoveAt(fromIndex) 
    DataGridView1.Rows.Insert(dragIndex, dragRow) 
    End If 
End Sub 

Private Sub DataGridView1_DragOver(ByVal sender As Object, _ 
            ByVal e As DragEventArgs) _ 
            Handles DataGridView1.DragOver 
    e.Effect = DragDropEffects.Move 
End Sub 

Los eventos de ratón:

Private Sub DataGridView1_MouseDown(ByVal sender As Object, _ 
            ByVal e As MouseEventArgs) _ 
            Handles DataGridView1.MouseDown 
    fromIndex = DataGridView1.HitTest(e.X, e.Y).RowIndex 
    If fromIndex > -1 Then 
    Dim dragSize As Size = SystemInformation.DragSize 
    dragRect = New Rectangle(New Point(e.X - (dragSize.Width/2), _ 
             e.Y - (dragSize.Height/2)), _ 
          dragSize) 
    Else 
    dragRect = Rectangle.Empty 
    End If 
End Sub 

Private Sub DataGridView1_MouseMove(ByVal sender As Object, _ 
            ByVal e As MouseEventArgs) _ 
            Handles DataGridView1.MouseMove 
    If (e.Button And MouseButtons.Left) = MouseButtons.Left Then 
    If (dragRect <> Rectangle.Empty _ 
    AndAlso Not dragRect.Contains(e.X, e.Y)) Then 
     DataGridView1.DoDragDrop(DataGridView1.Rows(fromIndex), _ 
           DragDropEffects.Move) 
    End If 
    End If 
End Sub 

Asegúrese de tener las propiedades de grillas AllowDrop establecidas en verdadero.

+0

¿Alguien puede responder por qué obtengo estos errores al arrastrar una fila en cualquier lugar de la vista de tabla de datos? 'Las filas no se pueden agregar programáticamente a la colección de filas de DataGridView cuando el control está enlazado a datos. –

+0

@ChadPatrick Como dice el error, su grilla está unida a datos (tiene una fuente de datos), lo que significa que no puede manipular la cuadrícula directamente. En su caso, necesita manipular la fuente de datos en su lugar. Si tiene problemas, publique una nueva pregunta y documente de manera adecuada. – LarsTech

+0

¿cómo puedo manipular la fuente de datos en su lugar? este es mi código para llenar el DataGridView: 'con = new SqlConnection con.ConnectionString = "Data Source = mssql; Initial Catalog = BASE DE DATOS; User ID = sa; contraseña =" con.Open() ADAP = New SqlDataAdapter ("SELECT * FROM tablename", con) ds = New System.Data.DataSet() adap.Fill (ds, "TableNew") Datagridview1.DataSource = ds.Tables (0) con.Close() ' –

2

ACTUALIZACIÓN:

En lugar de

If dragIndex < 0 Then dragIndex = DataGridView1.RowCount - 1 

cambio a

If dragIndex > -1 Then 
     'action if not selected in the row header and blank space 
else 
     'return error if selected in the column header and blank space 
end if 

a continuación, un error se produce cuando se arrastra una fila a la "zona de espacio en blanco", si no' créeme, debes probarlo.

el código final (sólo para la parte de "Los eventos de arrastre") es la siguiente:

Private Sub DataGridView1_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles DataGridView1.DragDrop 
     Dim p As Point = DataGridView1.PointToClient(New Point(e.X, e.Y)) 
     dragIndex = DataGridView1.HitTest(p.X, p.Y).RowIndex 
    'Determine if dragindex is valid row index  
    If dragIndex > -1 Then 
     If (e.Effect = DragDropEffects.Move) Then 
      Dim dragRow As DataGridViewRow = CType(e.Data.GetData(GetType(DataGridViewRow)), DataGridViewRow) 
      DataGridView1.Rows.RemoveAt(fromIndex) 
      DataGridView1.Rows.Insert(dragIndex, dragRow) 
      'Add this line of code if you want to put selected rows to the rows that change 
      DataGridView1.Rows(dragIndex).Selected = True 
     End If 
     Else 'Do any message here if selected in column header and blank space. 
     End If 
    End Sub 
0

gracias por todo, el código de trabajo. Solo recibí un error. Lo solucioné

si está configurada la vista de cuadrícula de datos "Habilitar edición", recibirá un error al tirar el espacio entre líneas. Puedes probar. Lo resuelto de la siguiente manera:

Private Sub DataGridView1(ByVal sender As Object, ByVal e As DragEventArgs) Handles DataGridView1.DragDrop 

    Dim p As Point = DataGridView1.PointToClient(New Point(e.X, e.Y)) 
        dragIndex = DataGridView1.HitTest(p.X, p.Y).RowIndex 
        If (e.Effect = DragDropEffects.Move) Then 
         Dim dragRow As DataGridViewRow = CType(e.Data.GetData(GetType(DataGridViewRow)), DataGridViewRow) 

         If dragIndex = DataGridView1.RowCount - 1 Then '**ADD THIS AREA** 
          DataGridView1.Rows.RemoveAt(fromIndex) 
          DataGridView1.Rows.Insert(DataGridView1.RowCount - 1, dragRow) 
         Else 
          If dragIndex < 0 Then dragIndex = DataGridView1.RowCount - 2 '**this is important** 
          DataGridView1.Rows.RemoveAt(fromIndex) 
          DataGridView1.Rows.Insert(dragIndex, dragRow) 
         End If 
        End If 
End Sub 

Gracias por toda la demás información

1

He aquí un control sin el error mencionado.

Conjunto AllowUserToOrderRows y AllowDrop-True en el Diseñador de Windows Forms y arrastre los encabezados de fila, no el contenido.

Imports System.ComponentModel 

Public Class BetterDataGridView 
    Inherits DataGridView 

    <Category("Behavior"), DefaultValue(False)> 
    Public Property AllowUserToOrderRows As Boolean = False 

    Protected Overrides Sub OnMouseDown(e As MouseEventArgs) 
     MyBase.OnMouseDown(e) 

     Dim hitInfo As HitTestInfo = HitTest(e.X, e.Y) 
     If AllowUserToOrderRows AndAlso 
       e.Button = MouseButtons.Left AndAlso 
       hitInfo.ColumnIndex = -1 AndAlso 
       ValidRow(hitInfo.RowIndex) Then 
      DoDragDrop(Rows(hitInfo.RowIndex), DragDropEffects.Move) 
     End If 
    End Sub 

    Protected Overrides Sub OnDragOver(e As DragEventArgs) 
     MyBase.OnDragOver(e) 

     Dim dragRow As DataGridViewRow = e.Data.GetData(GetType(DataGridViewRow)) 
     Dim targetIndex As Integer = GetRowIndex(e) 
     e.Effect = If(ValidRowDragDrop(dragRow, targetIndex), 
         DragDropEffects.Move, 
         DragDropEffects.None) 
    End Sub 

    Protected Overrides Sub OnDragDrop(e As DragEventArgs) 
     MyBase.OnDragDrop(e) 

     Dim dragRow As DataGridViewRow = e.Data.GetData(GetType(DataGridViewRow)) 
     Dim targetIndex As Integer = GetRowIndex(e) 

     If e.Effect = DragDropEffects.Move AndAlso ValidRowDragDrop(dragRow, targetIndex) Then 
      EndEdit() 

      Rows.Remove(dragRow) 
      Rows.Insert(targetIndex, dragRow) 

      ClearSelection() 
      dragRow.Selected = True 
     End If 
    End Sub 

    Protected Function ValidRow(rowIndex As Integer) As Boolean 
     Return rowIndex >= 0 AndAlso 
      rowIndex < Rows.Count - If(AllowUserToAddRows, 1, 0) 
    End Function 

    Protected Function GetRowIndex(e As DragEventArgs) As Integer 
     Dim clientPos As Point = PointToClient(New Point(e.X, e.Y)) 
     Return HitTest(clientPos.X, clientPos.Y).RowIndex 
    End Function 

    Protected Function ValidRowDragDrop(dragRow As DataGridViewRow, targetIndex As Integer) As Boolean 
     Return dragRow IsNot Nothing AndAlso 
      ValidRow(targetIndex) AndAlso 
      targetIndex <> dragRow.Index AndAlso 
      Rows.Contains(dragRow) 
    End Function 
End Class 
+1

Nota: el control solo aparece en la caja de herramientas después de haber creado el proyecto correctamente. – isedwards

+0

También he descubierto que si amplío algunos controles de WinForms, entonces el código nuevo debe compilarse como de 32 bits para poder funcionar (y, por lo tanto, solo se puede ver en la caja de herramientas una vez compilada con éxito como de 32 bits). Ver http://stackoverflow.com/a/26539992/1624894 para más detalles. – isedwards

0

1,5 mejoras para el evento GridView.DragDrop:

  1. La primera mejora del 50%, para evitar el error descriped también se puede utilizar

    Private Sub DgvSearchFieldCurrent_DragDrop(_ 
        ByVal sender As Object, ByVal e As DragEventArgs) _ 
        Handles DgvSearchFieldCurrent.DragDrop 
    
    Dim LclDgv As DataGridView = CType(sender, DataGridView) 
    
    If dragIndex > -1 AndAlso dragIndex < LclDgv.RowCount -1 Then 
    
  2. En segundo lugar es para ajustar el enfoque de la fila actual y la primera celda:

    LclDgv.Rows.Insert(dragIndex, dragRow) 
    
    LclDgv.Rows(fromIndex).Selected = False 
    LclDgv.Rows(dragIndex).Selected = True 
    
    For Each C As DataGridViewColumn In LclDgv.Columns 
        LclDgv(C.Index, fromIndex).Selected = False 
    Next 
    
    LclDgv(0, dragIndex).Selected = True 
    
Cuestiones relacionadas