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

  • As the mobile enterprise marketplace expands and customer needs grow more diverse, Samsung recognizes that solution partners and developers play an essential role by continually innovating to meet their customers' needs. Samsung works to provide these developers and partners with the latest tools and resources needed to create these solutions. Read this program guide to learn how the Samsung Enterprise Alliance Program provides partners and developers with Samsung enterprise software development kits (SDKs) …

  • Lenovo recommends Windows 8 Pro. "I dropped my laptop getting out of the taxi." This probably sounds familiar to most IT professionals. If your employees are traveling, you know their devices are in for a rough go. Whether it's a trip to the conference room or a convention out of town, any time equipment leaves a user's desk it is at risk of being put into harm's way. Stay connected at all times, whether at the office or on the go, with agile, durable, and flexible devices like the Lenovo® …

Most Popular Programming Stories

More for Developers

RSS Feeds

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