Tip: Auto Scroll While Implementing Drag & Drop for Reordering Rows in DataGridView

There are tons of articles detailing how to re-order rows in a data grid (here is a good one) but none handle this nuance of allowing the user to scroll up and down while dragging a row to a point beyond the displayed rows on the screen.

The Problem

Say a form hosts a datagrid that was sized to display 10 rows, and the gridvew has 100 rows. If the user has scrolled down to a point where the gridview displays rows 30 to 40, and if the user wants to move the 35th row to the second position, the gridview by default doesn't scroll up when user drags row 25 beyond the row header (or beyond row 40). This can be very annoying.

The Solution

This solution, in just four lines of code, implements the scroll up and scroll down feature when user drags a row beyond the datagridview's top and bottom bounds. After implementing the code to do a drag and drop re-ordering, in the DragOver event handler, add the following lines (the code assumes you have a datagridvew object called dataGridView1.)

private void dataGridView1_DragOver(object sender, DragEventArgs e)
   e.Effect = DragDropEffects.Move;

   if (e.Y <= PointToScreen(new Point(dataGridView1.Location.X,
      dataGridView1.FirstDisplayedScrollingRowIndex -= 1;
   if (e.Y >= PointToScreen(new Point(dataGridView1.Location.X+
      dataGridView1.Width, dataGridView1.Location.Y+
      dataGridView1.Height)).Y - 10)
   dataGridView1.FirstDisplayedScrollingRowIndex += 1;

Code Explained

Initially, I tried to handle this in the mouse move event when the LButton was down and the row index returned was equal to the datagridvew's FirstDisplayedScrollingRowIndex. But, this didn't work; when I used Debug.Write to trace the problem (because placing a break point in mouse move is next worst thing to HELL), I noticed that the move events were not fired when the LButton was down and after the cursor has moved out of the selected row (I assume that the do drag was eating away these events).

So, I changed my focus to the DragOver event handler. The code is pretty straightforward; it uses the following condition to check whether the user is dragging beyond the top visible row.

if (e.Y <= PointToScreen(new Point(dataGridView1.Location.X,
Note: The PointToScreen conversion as dataGridView1.Location.X will give co-ordinates relative to the hosted form and e.Y gives co-ordinates relative to the screen.

I am adding an offset of 40 just to accommodate for the header size (someone can probably write bettor code by calculating the header hight). Once the condition is satisfied, just call the code to increment or decrement the datagridview's FirstDisplayedScrollingRowIndex.

Happy coding.

About the Author

Naveen Konduri

I am what I am and I am not what I am not


  • Issue

    Posted by Aniket Samanta on 09/23/2014 04:24am

    Hi Naveen, Its really a very nice code. I have tried the code, however getting some exception message for the dataGridView1.FirstDisplayedScrollingRowIndex -= 1; condition. As the index cant be negative. I have updated the code to below, private void dataGridView1_DragOver(object sender, DragEventArgs e) { e.Effect = DragDropEffects.Move; 5. if (e.Y = PointToScreen(new Point(dataGridView1.Location.X+ dataGridView1.Width, dataGridView1.Location.Y+ 10. dataGridView1.Height)).Y - 10) dataGridView1.FirstDisplayedScrollingRowIndex += 1; } Thus removing the negativity parts, it working ok, but scroll up for the drag drop is not working. Its actually leading to scroll down as I am increasing the FirstDisplayedScrollingRowIndex. Could you please advice if there any way out of that? Thanks and Regards, Aniket

    • Fix

      Posted by Steve King on 12/17/2014 02:56am

      Hi apologies firstly as in write in VB but I'm sure you'll be able to convert. I also encountered the issue mentioned above but the fix is simply adding in another condition to the move up if statement to only act when first displayed row is over 0. I also changed the code to 1 if/elseif statement rather than 2 if statements given only up or down is possible at one time. Example e.Effect = DragDropEffects.Move If e.Y 0 Then dataGridView1.FirstDisplayedScrollingRowIndex -= 1 ElseIf e.Y = PointToScreen(New Point(dataGridView1.Location.X + dataGridView1.Width, dataGridView1.Location.Y + dataGridView1.Height)).Y - 10 Then dataGridView1.FirstDisplayedScrollingRowIndex += 1 End If

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Enterprises are increasingly looking to platform as a service (PaaS) to lower their costs and speed their time to market for new applications. Developing, deploying, and managing applications in the cloud eliminates the time and expense of managing a physical infrastructure to support them. PaaS offerings must deliver additional long-term benefits, such as a lower total cost of ownership (TCO), rapid scalability, and ease of integration, all while providing robust security and availability. This report …

  • Moving from an on-premises environment to Office 365 does not remove the need to plan for disruptions or reduce the business risk requirements for protecting email services. If anything, some risks increase with a move to the cloud. Read how to ease the transition every business faces if considering or already migrating to cloud email. This white paper discusses: Setting expectations when migrating to Office 365 Understanding the implications of relying solely on Exchange Online security Necessary archiving …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date