In un'applicazione Windows (Visual Studio) (VB) come trascinare una singola riga in un'altra posizione per consentire all'utente di riordinare la riga? Non ho ancora trovato esempi degni di questo.Come trascinare e rilasciare le righe all'interno della stessa vista dati Data
risposta
Ecco una versione VB da questo C# risposta: How could I Drag and Drop DataGridView Rows under each other?
Le variabili di classe forma:
Private fromIndex As Integer
Private dragIndex As Integer
Private dragRect As Rectangle
Gli eventi di trascinamento:
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
Gli eventi del mouse:
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
Assicurarsi che la proprietà delle griglie AllowDrop
sia impostata su true.
UPDATE:
Invece di
If dragIndex < 0 Then dragIndex = DataGridView1.RowCount - 1
modifica
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
poi un errore si verifica quando si trascina una riga alla "zona vuota", se si don' Credimi, devi provarlo.
il codice finale (solo per la parte "Gli eventi di trascinamento") è questo:
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
Grazie di tutto, il codice di lavoro. Stavo ricevendo solo un errore. L'ho risolto.
se è impostata la vista datagrid "Abilita modifica", si riceve un errore quando si inserisce un'interlinea. Puoi provare. Ho risolto come segue:
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
Grazie per tutte le altre informazioni
Ecco un controllo senza il bug menzionato.
Impostare AllowUserToOrderRows
e AllowDrop
a True
in Progettazione Windows Form e trascinare le intestazioni di riga, non il contenuto.
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
Nota: il controllo appare solo nella casella degli strumenti dopo aver completato correttamente il progetto. – isedwards
Ho anche scoperto che se estendo alcuni controlli WinForms, il nuovo codice deve essere compilato come 32-bit per funzionare (e quindi può essere visto solo nella toolbox una volta compilato con successo come 32-bit). Vedi http://stackoverflow.com/a/26539992/1624894 per i dettagli. – isedwards
1.5 miglioramenti per l'evento GridView.DragDrop:
Il primo miglioramento del 50%, per evitare l'errore descriped è anche possibile utilizzare
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
In secondo luogo è quello di impostare lo stato attivo alla riga corrente e la prima cella:
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
Qualcuno può rispondere perché ottengo questi errori durante il trascinamento di una riga in qualsiasi punto di Datagridview? 'Le righe non possono essere aggiunte a livello di codice alla raccolta di righe di DataGridView quando il controllo è legato ai dati. –
@ChadPatrick Come l'errore dice, la griglia è vincolata ai dati (su di essa è presente un'origine dati), il che significa che non è possibile manipolare la griglia direttamente. Nel tuo caso, devi invece manipolare l'origine dati. In caso di problemi, pubblica una nuova domanda e documentala in modo appropriato. – LarsTech
come posso invece manipolare l'origine dati? questo è il mio codice per riempire il DataGridView: 'con = new SqlConnection con.ConnectionString = "Data Source = mssql; Initial Catalog = DATABASE; User ID = sa; Password =" con.Open() adap = nuovo SqlDataAdapter ("SELECT * FROM tablename", con) ds = New System.Data.DataSet() adap.Fill (ds, "TableNew") Datagridview1.DataSource = ds.Tables (0) con.Close() ' –