在Windows应用程序(Visual Studio)(VB)中,如何将单个行拖放到另一个帖子以允许用户重新排序该行?我还没有找到任何有价值的例子。
答案 0 :(得分:6)
以下是此C#答案的vb版本:How could I Drag and Drop DataGridView Rows under each other?
表单类变量:
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。
答案 1 :(得分:2)
<强>更新强>
而不是
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
然后当你将一行拖到&#34;空白区域时发生错误&#34;如果你不相信我,你必须尝试。
最终代码(仅适用于部件&#34;拖动事件&#34;)是这样的:
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
答案 2 :(得分:1)
这是一个没有上述错误的控件。
在Windows窗体设计器中将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
答案 3 :(得分:0)
感谢您的一切,代码正常运行。我只得到一个错误。我解决了。
如果datagridview&#34;启用编辑&#34;如果设置,则在抛出行间距时会收到错误。你可以试试。我解决了它如下:
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
感谢所有其他信息
答案 4 :(得分:0)
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