5

Trong ứng dụng Windows (Visual Studio) (VB), làm cách nào để kéo và thả một hàng vào một bản đăng khác để cho phép người dùng sắp xếp lại hàng? Tôi chưa tìm thấy bất kỳ ví dụ đáng giá nào cho điều này.Cách kéo và thả hàng trong cùng một datagridview

Trả lời

5

Đây là một phiên bản vb từ C# câu trả lời này: How could I Drag and Drop DataGridView Rows under each other?

Các biến lớp mẫu:

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

Các sự kiện kéo:

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 

Các sự kiện chuột:

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 

Đảm bảo bạn có lưới AllowDrop thuộc tính được đặt thành true.

+0

Ai đó có thể trả lời tại sao tôi gặp phải các lỗi này khi kéo một hàng ở bất kỳ vị trí nào trong Chế độ xem dữ liệu? 'Hàng không thể được thêm theo chương trình vào bộ sưu tập hàng của DataGridView khi điều khiển bị ràng buộc dữ liệu.' –

+0

@ChadPatrick Giống như lỗi nói, lưới của bạn là dữ liệu bị ràng buộc (bạn có nguồn dữ liệu trên đó), có nghĩa là bạn không thể thao tác lưới điện trực tiếp. Trong trường hợp của bạn, bạn cần phải thao tác nguồn dữ liệu thay thế. Nếu bạn gặp vấn đề, hãy đăng câu hỏi mới và ghi lại nó một cách thích hợp. – LarsTech

+0

Tôi có thể thao tác với nguồn dữ liệu như thế nào? đây là mã của tôi để điền vào datagridview: 'con = New SqlConnection con.ConnectionString =" Nguồn dữ liệu = mssql; Danh mục ban đầu = DATABASE; ID người dùng = sa; Mật khẩu = " con.Open() adap = New SqlDataAdapter ("SELECT * FROM tablename", con) ds = Hệ thống mới.Data.DataSet() adap.Fill (ds, "Bảng mới") Datagridview1.DataSource = ds.Tables (0) con.Close() ' –

2

UPDATE:

Thay vì

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

thay đổi

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 

sau đó một lỗi xảy ra khi bạn kéo một hàng để "vùng trống", nếu bạn don' Tôi tin rằng, bạn phải thử nó.

mã cuối cùng (Chỉ dành cho phần "Các sự kiện kéo") là thế này:

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

Cảm ơn bạn vì tất cả, mã làm việc. Tôi chỉ nhận được một lỗi. Tôi đã giải quyết nó.

nếu chế độ xem dữ liệu "Bật chỉnh sửa" được đặt, bạn nhận được lỗi khi bạn ném khoảng cách dòng. Bạn co thể thử. Tôi giải quyết nó như sau:

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 

Cảm ơn tất cả các thông tin khác

1

Dưới đây là một điều khiển mà không có lỗi nói.

Đặt AllowUserToOrderRowsAllowDrop to True trong Windows Forms Designer và kéo tiêu đề hàng, chứ không phải nội dung.

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

Lưu ý: điều khiển chỉ xuất hiện trong hộp công cụ sau khi bạn đã xây dựng thành công dự án. – isedwards

+0

Tôi cũng thấy rằng nếu tôi mở rộng một số điều khiển WinForms thì mã mới phải được biên dịch dưới dạng 32 bit để hoạt động (và do đó chỉ có thể thấy trong hộp công cụ khi được biên dịch thành công là 32 bit). Xem http://stackoverflow.com/a/26539992/1624894 để biết chi tiết. – isedwards

0

1,5 cải tiến cho sự kiện GridView.DragDrop:

  1. Sự cải thiện 50% đầu tiên, Để tránh lỗi này descriped bạn cũng có thể sử dụng

    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. Thứ hai là để thiết lập tập trung vào hàng hiện tại và ô đầu tiên:

    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