Windowsアプリ(Visual Studio)(VB)で、ユーザーが行を並べ替えられるように、1つの行を別の位置にドラッグアンドドロップするにはどうすればよいですか?これにふさわしい例はまだ見つかりません。
5 に答える
この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
gridsAllowDrop
プロパティが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フォームデザイナで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
イベントGridView.DragDropの1.5の改善:
最初の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
2つ目は、現在の行と最初のセルにフォーカスを設定することです。
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
コードが機能しているすべてに感謝します。エラーが1つだけ発生しました。私はそれを解決しました。
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
他のすべての情報をありがとう