Drag & Drop Reorder of Row

I tried the Drag & Drog reorder of row as shown in the DGV FAQ Doc, but it doesn't work.

Selected row was removed but no new row being added at destination.

Anyone know the reason

Thanks,



Answer this question

Drag & Drop Reorder of Row

  • Figo Fei - MSFT

    Is the grid databound The sample in the FAQ only works for unbound grid.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    -mark

    DataGridView Program Manager

    Microsoft

    This post is provided "as-is"

     

     


  • Paulo S&amp;#233;rgio

    I ran across this same issue a while back when working on a project.

    I was suprised no one had encapsulated the grid code from drag and drop into an extended control that you could just add to your toolkit and drop on the page.

    So...

    I added one myself.

    www.codeplex.com/dragdropgrid


  • Stumkar

    Marvelous !

    It works! Amazing Mark ;)

    Thanks.


  • Bruce HK

    What is your code where the DataGridView is databound. My guess is the problem is that you are directly adding to the table and not to the view or adapter. I'll try some thing out today and see if I can get this to work.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    -mark

    DataGridView Program Manager

    Microsoft

    This post is provided "as-is"

     


  • Peterssitje

    So here is what i modified in the DragDrop code -- instead of removing and inserting in the DataGridView, I remove and insert into the DataTable. In my case my datatable (Customers) is off the Northwind DataSet:


        // get the row data from row before removing and add to new row
        object[] rowArray = northwindDataSet.Customers.Rows[rowIndexFromMouseDown].ItemArray;
        DataRow row = northwindDataSet.Customers.NewRow();
        row.ItemArray = rowArray;
       
        // remove old row and insert new row
        northwindDataSet.Customers.Rows.RemoveAt(rowIndexFromMouseDown);               
        northwindDataSet.Customers.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop);

     
    Let me know if this works for you!
    -mark
    DataGridView Program Manager
    Microsoft
    This post is provided "as-is"

     


  • Mule

    Removing and inserting the row will not require you to databind again and it won't be a reset, so you should be fine.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    -mark

    DataGridView Program Manager

    Microsoft

    This post is provided "as-is"

     


  • randomAxim

    Hi,

    I'm sorry, but using the code of DataGridView Faqs and the code above, it doesn't work properly, the row to be reordered always appear as the first row, this is the code, I would appreciate if someone can help me to review this code:

    Friend dragBoxFromMouseDown As Rectangle
    Friend rowIndexFromMouseDown As Integer
    Friend rowIndexOfItemUnderMouseToDrop As Integer
    Friend TempDataTable As DataTable

    Private Sub dataGridView1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseMove

            If ((e.Button + Windows.Forms.MouseButtons.Left) = Windows.Forms.MouseButtons.Left) Then

             ' If the mouse moves outside the rectangle, start the drag.
                     If (dragBoxFromMouseDown <> Rectangle.Empty And dragBoxFromMouseDown.Contains(e.X, e.Y)) Then
                    ' Proceed with the drag and drop, passing in the list item. 
                      Dim dropEffect As DragDropEffects = DataGridView1.DoDragDrop(DataGridView1.Rows(rowIndexFromMouseDown), DragDropEffects.Move)
                     End If
             End If
    End Sub
    ____________________________________________________________________________________________________________

    Private Sub DataGridView1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseDown

    ' Get the index of the item the mouse is below.
    rowIndexFromMouseDown = DataGridView1.HitTest(e.X, e.Y).RowIndex

    If rowIndexFromMouseDown <> -1 Then
              ' Remember the point where the mouse down occurred.
             
    ' The DragSize indicates the size that the mouse can move 
              
    ' before a drag event should be started.

              Dim dragSize As Size = SystemInformation.DragSize

               ' Create a rectangle using the DragSize, with the mouse position being
              
    ' at the center of the rectangle.
               
    dragBoxFromMouseDown = New Rectangle(New Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize)
    Else
                ' Reset the rectangle if the mouse is not over an item in the ListBox.
               
    dragBoxFromMouseDown = Rectangle.Empty

    End If

    End Sub
    ________________________________________________________________________________________________________

    Private Sub DataGridView1_DragOver1(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView1.DragOver
                  e.Effect = DragDropEffects.Move
    End Sub
    ________________________________________________________________________________________________________

    Private Sub DataGridView1_DragDrop1(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView1.DragDrop

    ' get the row data from row before removing and add to new row
    Dim rowArray As Object() = TempDataTable.Rows(rowIndexFromMouseDown).ItemArray
    Dim row As DataRow = TempDataTable.NewRow()
    row.ItemArray = rowArray

    'remove old row and insert new row
    TempDataTable.Rows.RemoveAt(rowIndexFromMouseDown)
    TempDataTable.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop)

    End Sub

    Where TempDataTable is a DataTable that works as the DataGridView DataSource. Any help would be eternally appreciated.

    Thanks in advance.

    George

     

     


     


  • Winanjaya

     Mark Rideout wrote:
     to remove and insert the row into the datasource

    Thanks for your hints Mark!

    Changing the order of "row" in the dataset/datatable, and then fire a databind again make sense. However, as I stated in another post before, do you think the DataBindComplete event will be fired "again" unexpectedly if I change the order of DataSet and then re-databind again If so, all of the selected choice in other column, such as DGVCheckBoxColumn will be lost

    Thanks,


  • ts11

    Thanks Mark, I tried to modify your FAQ code snippet but I still can't figure out how I can reorder rows in the DataTable level:

    private void dgvColumns_DragDrop(object sender, DragEventArgs e) {
    // The mouse locations are relative to the screen, so they must be
    // converted to client coordinates.
    Point clientPoint = dgvColumns.PointToClient(new Point(e.X, e.Y));

    // Get the row index of the item the mouse is below.
    rowIndexOfItemUnderMouseToDrop = dgvColumns.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

    // If the drag operation was a move then remove and insert the row.
    if (e.Effect == DragDropEffects.Move) {
    DataGridViewRow rToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow;
    Int32 intRToMove = rToMove.Index;
    DataRow drToMove = Ds.Tables[0].Rows[intRToMove];
    Ds.Tables[0].Rows.RemoveAt(intRToMove);
    Ds.Tables[0].Rows.InsertAt(drToMove, rowIndexOfItemUnderMouseToDrop);
    }

    What I did is:

    1. Get the selected datagridviewrow
    2. Get its Index
    3. Get the "DataRow" on the DataTable base on this Index
    4. Remove 'this' datarow from the DataTable
    5. Insert 'this' DataRow at the specific row index

    However, the selected (row being dragged) was remove successfully while no datarow inserted into the Grid.

    Thanks,


  • ArildFines

    Hi Mark,

    Yes, the datagrid is databounded, and how come a DataGridView contain data without DataBinding Create a collection of "object" base on DataSet and then bind to the Grid can be an alternative

    Thanks,


  • WordScript

    The DataGridView supports many different data modes. Check out the FAQ. You can directly add rows to the DataGridView when in unbound mode. You can also use VirtualMode where you dynamically provide data as needed. Or you can use databound mode where the data comes from a datasource.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    You'll have to modify the sample in the FAQ to remove and insert the row into the datasource. I think someone on the forums already has done this, so do a search also.

     

    -mark

    DataGridView Program Manager

    Microsoft

    This post is provided "as-is"

     

     


  • AmauryR

    Hi Mark,

    Yes, I'm databinding a DataSet / DataTable to the DGV directly by specifying the DataSource and DataMember properties. BTW, I change to Ds.Tables[0].DefaultView and the result is just the same.

    Thanks and wait for your feedback.


  • Drag & Drop Reorder of Row