[英]How to drag and drop row within the same datagridview
在Windows應用程序(Visual Studio)(VB)中,如何將單個行拖放到另一個帖子以允許用戶重新排序該行? 我還沒有找到任何有價值的例子。
這是來自這個C#答案的vb版本: 我怎樣才能將DataGridView行拖放到彼此之下?
表單類變量:
Private fromIndex As Integer
Private dragIndex As Integer
Private dragRect As Rectangle
拖動事件:
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
鼠標事件:
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
確保將網格AllowDrop
屬性設置為true。
更新:
代替
If dragIndex < 0 Then dragIndex = DataGridView1.RowCount - 1
改成
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
當你將一行拖到“空白區域”時會出現錯誤,如果你不相信我,你必須嘗試一下。
最終代碼(僅用於“拖動事件”部分)是這樣的:
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
這是一個沒有上述錯誤的控件。
在Windows窗體設計器AllowDrop
AllowUserToOrderRows
和AllowDrop
設置為True
並拖動行標題,而不是內容。
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
謝謝你的一切,代碼工作。 我只得到一個錯誤。 我解決了
如果設置了datagridview“啟用編輯”,則在拋出行間距時會收到錯誤。 你可以試試。 我解決了如下:
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
感謝所有其他信息
1.5事件GridView.DragDrop的改進:
前50%的改進,為避免描述錯誤,您也可以使用
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
第二是將焦點設置為當前行和第一個單元格:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.