Click here to Skip to main content
11,434,799 members (47,604 online)
Click here to Skip to main content

Drag and Drop ListView row reordering

, 11 Nov 2003
Rate this:
Please Sign up or sign in to vote.
This article presents a simple ListView control that provides row reordering using Drag and Drop.

Introduction

An application I worked on required a mechanism whereby the user could rearrange the index of a row within a ListView control at runtime. For this, I wanted to use Drag and Drop, however after trailing through the Internet for some examples, I was unable to find something specific to C#, therefore I decided to implement my own.

Using the code

The ListView control presented here adds the property AllowRowReorder to the existing .NET ListView, which enables or disables the control's ability to reorder it rows.

In order to provide Drag and Drop support to the control, the methods OnItemDrag, OnDragEnter and OnDragDrop of the base control must be overridden. OnItemDrag is the method called once the control detects that a Drag and Drop operation has begun. It is here that any pre 'Drag and Drop' logic must be performed; this entails ensuring that row reordering has been enabled. Finally to inform the ListView that the Drag and Drop operation is valid, the DoDragDrop method is called, the first parameter being the Drag data, which identifies the object to be dragged and needs to be a String, Bitmap or a MetaFile. For the ListView provided, this is a hard-coded string, which will be used in the OnDragEnter method for Drop validation, since the items to be dragged will implicitly be the currently selected ListView items.

protected override void OnItemDrag(ItemDragEventArgs e)
{
  base.OnItemDrag(e);
  if(!this.AllowRowReorder)
  {
    return;
  }
  base.DoDragDrop(REORDER, DragDropEffects.Move);
}

The OnDragEnter validates whether or not the item being dragged, as identified by the DragEventArgs.Data object, can be dropped into the control. Note that when Drag and Drop is enabled within the control, it must provide logic to handle drag events from all drag enabled sources. The ListView provided simply ensures that the data passed matches the hard-coded value supplied by the OnItemDrag method.

protected override void OnDragEnter(DragEventArgs e)
{
  base.OnDragEnter(e);
  if(!this.AllowRowReorder)
  {
    e.Effect = DragDropEffects.None;
    return;
  }
  if(!e.Data.GetDataPresent(DataFormats.Text))
  {
    e.Effect = DragDropEffects.None;
    return;
  }
  String text = (String)e.Data.GetData(REORDER.GetType());
  if(text.CompareTo(REORDER)==0)
  {
    e.Effect = DragDropEffects.Move;
  }
  else
  {
    e.Effect = DragDropEffects.None; 
  }
}

Subsequently, OnDragOver ensures the continuing validity of the Drop operation as you move the mouse over the items in the control.

protected override void OnDragOver(DragEventArgs e)
{
  if(!this.AllowRowReorder)
  {
    e.Effect = DragDropEffects.None;
    return;
  }
  if(!e.Data.GetDataPresent(DataFormats.Text))
  {
    e.Effect = DragDropEffects.None;
    return;
  }
  Point cp = base.PointToClient(new Point(e.X, e.Y));
  ListViewItem hoverItem = base.GetItemAt(cp.X, cp.Y);
  if(hoverItem==null)
  {
    e.Effect = DragDropEffects.None;
    return;
  }
  foreach(ListViewItem moveItem in base.SelectedItems)
  {
    if(moveItem.Index==hoverItem.Index)
    {
        e.Effect = DragDropEffects.None;
        hoverItem.EnsureVisible();
        return;
    }
  }
  base.OnDragOver(e);
  String text = (String)e.Data.GetData(REORDER.GetType());
  if(text.CompareTo(REORDER)==0)
  {
    e.Effect = DragDropEffects.Move;
    hoverItem.EnsureVisible();
  }
  else
  {
    e.Effect = DragDropEffects.None;        
  }
}

Finally OnDragDrop performs the actual Drop operation, this includes identifying the ListViewItems to be moved and the row index they will be moved to. Notice that I’m assuming that the ListViewItems to be moved are the control's currently selected items.

protected override void OnDragDrop(DragEventArgs e)
{
  base.OnDragDrop(e);
  if(!this.AllowRowReorder)
  {
    return;
  }
  if(base.SelectedItems.Count==0)
  {
    return;
  }
  Point cp = base.PointToClient(new Point(e.X, e.Y));
  ListViewItem dragToItem = base.GetItemAt(cp.X, cp.Y);
  if(dragToItem==null)
  {
    return;
  }
  int dropIndex = dragToItem.Index;
  if(dropIndex>base.SelectedItems[0].Index)
  {
    dropIndex++;
  }
  ArrayList insertItems = 
    new ArrayList(base.SelectedItems.Count);
  foreach(ListViewItem item in base.SelectedItems)
  {
    insertItems.Add(item.Clone());
  }
  for(int i=insertItems.Count-1;i>=0;i--)
  {
    ListViewItem insertItem =
     (ListViewItem)insertItems[i];
    base.Items.Insert(dropIndex, insertItem);
  }
  foreach(ListViewItem removeItem in base.SelectedItems)
  {
    base.Items.Remove(removeItem);
  }
}

Downloads

Source and demo projects have been created using #Develop.

Update

  • 6th October 2003 - Fix for reordering problem when dragging multiple items.
  • 10 November 2003 – Updated for automatic scrolling during a Drag operation (suggestion from JayBarry and Brian Pierson)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

David Boland
Web Developer
United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 1 Pin
Trần Hùng Cường4-Mar-14 23:24
memberTrần Hùng Cường4-Mar-14 23:24 
GeneralA vrey nice and relatively simple enhancement to the ListView control, thanks Pin
Member 187983216-Sep-13 12:46
memberMember 187983216-Sep-13 12:46 
QuestionI don't know how to use the listviewex Pin
Member 474288830-Jun-11 13:33
memberMember 474288830-Jun-11 13:33 
GeneralMy vote of 5 Pin
Big D15-Feb-11 9:09
memberBig D15-Feb-11 9:09 
GeneralDrag and Drop between groups Pin
esofter12-Oct-09 1:44
memberesofter12-Oct-09 1:44 
QuestionDrag and Drop? Pin
codehack23-Apr-09 10:56
membercodehack23-Apr-09 10:56 
Generalitems controls in a listview Pin
adsana14-Apr-09 0:23
memberadsana14-Apr-09 0:23 
QuestionHow to use it with CheckedListBox Pin
milan.fratrik14-Jul-08 1:04
membermilan.fratrik14-Jul-08 1:04 
GeneralListView control Pin
Pdeveloper27-Jun-08 6:05
memberPdeveloper27-Jun-08 6:05 
GeneralDoes not work inside a WPF UserControl inside a MMC 3.0 Container [modified] Pin
Ahead199922-Apr-08 4:11
memberAhead199922-Apr-08 4:11 
GeneralUsing the code Pin
shamsteady9-Mar-07 9:12
membershamsteady9-Mar-07 9:12 
GeneralAfterRowReorder Event Pin
Tom Lawrance13-Oct-06 3:02
memberTom Lawrance13-Oct-06 3:02 
GeneralAlternate method... Pin
camillo12-Jul-06 4:56
membercamillo12-Jul-06 4:56 
GeneralRe: Alternate method... Pin
Pat Kujawa28-Apr-10 7:39
memberPat Kujawa28-Apr-10 7:39 
GeneralRe: Alternate method... Pin
BillWoodruff21-Mar-13 7:49
memberBillWoodruff21-Mar-13 7:49 
GeneralDoesn´t works in View.LargeIcon mode Pin
emo_casares22-Apr-05 6:15
memberemo_casares22-Apr-05 6:15 
GeneralRe: Doesn´t works in View.LargeIcon mode Pin
David Boland25-Apr-05 5:40
memberDavid Boland25-Apr-05 5:40 
GeneralRe: Doesn´t works in View.LargeIcon mode Pin
uv5074-Oct-05 2:59
memberuv5074-Oct-05 2:59 
GeneralRe: Doesn´t works in View.LargeIcon mode Pin
David Boland6-Oct-05 1:55
memberDavid Boland6-Oct-05 1:55 
GeneralRe: Doesn´t works in View.LargeIcon mode Pin
aryxmyth8-Apr-06 7:36
memberaryxmyth8-Apr-06 7:36 
GeneralRe: Doesn´t works in View.LargeIcon mode [modified] Pin
Milky Way18-Jun-06 22:43
memberMilky Way18-Jun-06 22:43 
AnswerRe: Doesn´t works in View.LargeIcon mode Pin
ntiagobr24-Oct-06 10:01
memberntiagobr24-Oct-06 10:01 
QuestionScrolling within the listbox? Pin
JayBarry29-Oct-03 8:17
memberJayBarry29-Oct-03 8:17 
AnswerRe: Scrolling within the listbox? Pin
JayBarry29-Oct-03 9:45
memberJayBarry29-Oct-03 9:45 
GeneralRe: Scrolling within the listbox? Pin
Brian Pierson10-Nov-03 5:54
memberBrian Pierson10-Nov-03 5:54 
GeneralRe: Scrolling within the listbox? Pin
David Boland10-Nov-03 6:44
memberDavid Boland10-Nov-03 6:44 
QuestionHow to sort rows as well as columns? Pin
Bakutotsu15-Oct-03 7:22
memberBakutotsu15-Oct-03 7:22 
AnswerRe: How to sort rows as well as columns? Pin
David Boland15-Oct-03 23:57
memberDavid Boland15-Oct-03 23:57 
GeneralDragging more than one item Pin
Brian Heitt24-Aug-03 8:16
memberBrian Heitt24-Aug-03 8:16 
GeneralRe: Dragging more than one item Pin
JayBarry3-Oct-03 9:47
memberJayBarry3-Oct-03 9:47 
GeneralRe: Dragging more than one item Pin
David Boland5-Oct-03 23:38
memberDavid Boland5-Oct-03 23:38 
QuestionReorder ?? Pin
azusakt4-Aug-03 17:25
memberazusakt4-Aug-03 17:25 
AnswerRe: Reorder ?? Pin
dboland5-Aug-03 0:09
memberdboland5-Aug-03 0:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150428.2 | Last Updated 12 Nov 2003
Article Copyright 2003 by David Boland
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid