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.Location.Y)).Y+40)
      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,
   dataGridView1.Location.Y)).Y+40)
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

Comments

  • There are no comments yet. Be the first to comment!

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

Top White Papers and Webcasts

  • "Security" is the number one issue holding business leaders back from the cloud. But does the reality match the perception? Keeping data close to home, on premises, makes business and IT leaders feel inherently more secure. But the truth is, cloud solutions can offer companies real, tangible security advantages. Before you assume that on-site is the only way to keep data safe, it's worth taking a comprehensive approach to evaluating risks. Doing so can lead to big benefits.

  • Event Date: April 15, 2014 The ability to effectively set sales goals, assign quotas and territories, bring new people on board and quickly make adjustments to the sales force is often crucial to success--and to the field experience! But for sales operations leaders, managing the administrative processes, systems, data and various departments to get it all right can often be difficult, inefficient and manually intensive. Register for this webinar and learn how you can: Align sales goals, quotas and …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds