Click here to Skip to main content
Click here to Skip to main content

Drag and Drop List View

, 12 May 2004
Rate this:
Please Sign up or sign in to vote.
Drag and Drop list items within list views or to other list views without manual intervention.

Sample Image - DragAndDropListView.gif

Introduction

An upcoming application at work required me to have drag and drop functionality between many different ListViews or DataGrids. When I got word, I decided to start searching the Internet and find a pre-existing free control that I could use. My personal requirements were that the ListView or DataGrid needed to have the ability to move rows around within its own control, but also allow me to move rows to other controls. My initial sorting pointed me towards Drag and Drop ListView row reordering by David Boland. As his control allowed users to reorder items in a ListView, it lacked support for moving to other ListViews as well as letting the user know where the new rows are to be placed. This control is somewhat similar to David's, however, it was rewritten only using David's code as a reference.

Using the Code

The DragAndDropListView control inherits from ListView, and provides native support for dragging and dropping ListItems to reorder them or move them to other DragAndDropListView controls. Because it needs to utilize Drag and Drop functionality, I had to override the OnDragDrop, OnDragOver, OnDragEnter, OnItemDrag, OnLostFocus, and OnDragLeave to provide the functionality.

When an item is selected and started to be dragged, OnItemDrag gets called which starts the Drag and Drop functionality by retrieving the control it originates from as well as the selected items. Both of these are stored in a private class that is passed around in the data of the drag and drop events.

protected override void OnItemDrag(ItemDragEventArgs e)
{
 if(!m_allowReorder)
 {
  base.OnItemDrag(e);
  return;
 }

 base.DoDragDrop(GetDataForDragDrop(), DragDropEffects.Move);

 base.OnItemDrag(e);
}

As the user moves the selected list items over the ListView, OnDragOver is called. This method basically determines if the selected items to be dragged & dropped can actually be dragged & dropped. By checking to see if the item it's currently hovering over is not one of the list items being moved, it either displays the move cursor or denied cursor. If the user is trying to drop the items into an area that doesn't have a list item, it will still allow you, thus allowing you to place and reorder items in any order.

protected override void OnDragOver(DragEventArgs drgevent)
{
 if(!m_allowReorder)
 {
  base.OnDragOver(drgevent);
  return;
 }
 if(!drgevent.Data.GetDataPresent(typeof(DragItemData).ToString()))
 {
  drgevent.Effect = DragDropEffects.None;
  return;
 }

 if(base.Items.Count > 0)
 {
  Point clientPoint = base.PointToClient(new Point(drgevent.X, drgevent.Y));
  ListViewItem hoverItem = base.GetItemAt(clientPoint.X, clientPoint.Y);

  Graphics g = this.CreateGraphics();

  if(hoverItem == null)
  {
   drgevent.Effect = DragDropEffects.Move;

   if(m_previousItem != null)
   {
    m_previousItem = null;
    Invalidate();
   }

   hoverItem = base.Items[base.Items.Count - 1];

   if(this.View == View.Details || this.View == View.List)
   {
    g.DrawLine(new Pen(m_lineColor, 2), new Point(hoverItem.Bounds.X, 
     hoverItem.Bounds.Y + hoverItem.Bounds.Height), 
     new Point(hoverItem.Bounds.X + 
     this.Bounds.Width, hoverItem.Bounds.Y + 
     hoverItem.Bounds.Height));
    g.FillPolygon(new SolidBrush(m_lineColor),
     new Point[] {new Point(hoverItem.Bounds.X, 
     hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5), 
     new Point(hoverItem.Bounds.X + 5, hoverItem.Bounds.Y + 
     hoverItem.Bounds.Height), 
     new Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + 
     hoverItem.Bounds.Height + 5)});
    g.FillPolygon(new SolidBrush(m_lineColor), 
     new Point[] {new Point(this.Bounds.Width - 4, 
     hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5), 
     new Point(this.Bounds.Width - 9, 
     hoverItem.Bounds.Y + hoverItem.Bounds.Height), 
     new Point(this.Bounds.Width - 4, 
     hoverItem.Bounds.Y + hoverItem.Bounds.Height + 5)});
   }
   else
   {
    g.DrawLine(new Pen(m_lineColor, 2), 
     new Point(hoverItem.Bounds.X + 
     hoverItem.Bounds.Width, hoverItem.Bounds.Y), 
     new Point(hoverItem.Bounds.X + 
     hoverItem.Bounds.Width, hoverItem.Bounds.Y + 
     hoverItem.Bounds.Height));
    g.FillPolygon(new SolidBrush(m_lineColor), 
     new Point[] {new Point(hoverItem.Bounds.X + 
     hoverItem.Bounds.Width - 5, hoverItem.Bounds.Y), 
     new Point(hoverItem.Bounds.X + 
     hoverItem.Bounds.Width + 5, hoverItem.Bounds.Y), 
     new Point(hoverItem.Bounds.X + 
     hoverItem.Bounds.Width, hoverItem.Bounds.Y + 5)});
    g.FillPolygon(new SolidBrush(m_lineColor), 
     new Point[] {new Point(hoverItem.Bounds.X + 
     hoverItem.Bounds.Width - 5, hoverItem.Bounds.Y + 
     hoverItem.Bounds.Height), 
     new Point(hoverItem.Bounds.X + 
     hoverItem.Bounds.Width + 5, hoverItem.Bounds.Y + 
     hoverItem.Bounds.Height), 
     new Point(hoverItem.Bounds.X + hoverItem.Bounds.Width, 
     hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5)});
   }

   base.OnDragOver(drgevent);

   return;
  }

  if((m_previousItem != null && 
    m_previousItem != hoverItem) || m_previousItem == null)
  {
   this.Invalidate();
  }

  m_previousItem = hoverItem;

  if(this.View == View.Details || this.View == View.List)
  {
   g.DrawLine(new Pen(m_lineColor, 2), new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y), new Point(hoverItem.Bounds.X + this.Bounds.Width, 
    hoverItem.Bounds.Y));
   g.FillPolygon(new SolidBrush(m_lineColor), 
    new Point[] {new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y - 5), new Point(hoverItem.Bounds.X + 5, 
    hoverItem.Bounds.Y), new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y + 5)});
   g.FillPolygon(new SolidBrush(m_lineColor), 
    new Point[] {new Point(this.Bounds.Width - 4, 
    hoverItem.Bounds.Y - 5), new Point(this.Bounds.Width - 9, 
    hoverItem.Bounds.Y), new Point(this.Bounds.Width - 4, 
    hoverItem.Bounds.Y + 5)});
  }
  else
  {
   g.DrawLine(new Pen(m_lineColor, 2), 
    new Point(hoverItem.Bounds.X, hoverItem.Bounds.Y), 
    new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height));
   g.FillPolygon(new SolidBrush(m_lineColor), 
    new Point[] {new Point(hoverItem.Bounds.X - 5, 
    hoverItem.Bounds.Y), 
    new Point(hoverItem.Bounds.X + 5, hoverItem.Bounds.Y), 
    new Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + 5)});
   g.FillPolygon(new SolidBrush(m_lineColor), 
    new Point[] {new Point(hoverItem.Bounds.X - 5, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height), 
    new Point(hoverItem.Bounds.X + 5, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height), 
    new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5)});

  }

  foreach(ListViewItem itemToMove in base.SelectedItems)
  {
   if(itemToMove.Index == hoverItem.Index)
   {
    drgevent.Effect = DragDropEffects.None;
    hoverItem.EnsureVisible();
    return;
   }
  }

  hoverItem.EnsureVisible();
 }

 drgevent.Effect = DragDropEffects.Move;

 base.OnDragOver(drgevent);
}

One of the really cool things that I wanted to do, was to add a line either above or below the hovered list item, however, this really didn't pose an easy feat at first. To figure this out, I had 2 actual implementations of creating the line, 1 for when you were hovering over a list item, and 1 for when you were in an empty area. When you were hovering over a list item, the line needed to be added between that item and the item above it. If the user is currently over the empty area, and items existed, then the line would be added to the bottom of the very last item. Below is the code that shows how to add the line and arrows on both side:

[Add the Line to the Last Item on Bottom]
g.DrawLine(new Pen(Brushes.Red, 2), new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height), 
    new Point(hoverItem.Bounds.X + this.Bounds.Width, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height));
g.FillPolygon(Brushes.Red, new Point[] {new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5), 
    new Point(hoverItem.Bounds.X + 5, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height), 
    new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height + 5)});
g.FillPolygon(Brushes.Red, new Point[] {new Point(this.Bounds.Width - 4, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5), 
    new Point(this.Bounds.Width - 9, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height), 
    new Point(this.Bounds.Width - 4, 
    hoverItem.Bounds.Y + hoverItem.Bounds.Height + 5)});
[Add the Line to the Top of the Current Item]
g.DrawLine(new Pen(Brushes.Red, 2), new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y), new Point(hoverItem.Bounds.X + 
    this.Bounds.Width, hoverItem.Bounds.Y));
g.FillPolygon(Brushes.Red, new Point[] {new Point(hoverItem.Bounds.X, 
    hoverItem.Bounds.Y - 5), new Point(hoverItem.Bounds.X + 5, 
    hoverItem.Bounds.Y), 
    new Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + 5)});
g.FillPolygon(Brushes.Red, new Point[] {new Point(this.Bounds.Width - 4, 
    hoverItem.Bounds.Y - 5), new Point(this.Bounds.Width - 9, 
    hoverItem.Bounds.Y), 
    new Point(this.Bounds.Width - 4, hoverItem.Bounds.Y + 5)});

Previous versions of this article stated that lines would only be drawn if it was in Details or Line mode, however this updated version includes both Small Icon List and Large Icon List replacing horizontal lines with vertical lines. The demo has also been updated, so you can test this method out as well.

As the user is dragging the selected items around the form, OnLostFocus and OnDragLeave are utilized to invalidate the form so the drawn lines are erased.

Lastly, OnDragDrop is called whenever the user drops the selected items into a DragAndDropListView. This method determines if the items to be dropped are from the current DragAndDropListView or from another DragAndDropListView. At which point, the items are appended to the end, or above the hovered item. Finally, the selected items are removed from the respective DragAndDropListView.

protected override void OnDragDrop(DragEventArgs drgevent)
{
 if(!m_allowReorder)
 {
  base.OnDragDrop(drgevent);
  return;
 }

 Point clientPoint = base.PointToClient(new Point(drgevent.X, drgevent.Y));
 ListViewItem hoverItem = base.GetItemAt(clientPoint.X, clientPoint.Y);

 if(!drgevent.Data.GetDataPresent(typeof(DragItemData).ToString()) || 
  ((DragItemData) 
   drgevent.Data.GetData(typeof(DragItemData).ToString())).ListView == null ||
  ((DragItemData) 
   drgevent.Data.GetData(typeof(DragItemData).ToSTring())).DragItems.Count == 0)
     return;
  
 DragItemData data = 
   (DragItemData) drgevent.Data.GetData(typeof(DragItemData).ToString());

 if(hoverItem == null)
 {
  for(int i=0; i<insertItems.Count; i++)
  {
   ListViewItem newItem = (ListViewItem) insertItems[i];
   base.Items.Add(newItem);
  }
 }
 else
 {
  int hoverIndex = hoverItem.Index;

  if(this == data.ListView)
  {
   if(hoverIndex > base.SelectedItems[0].Index)
    hoverIndex++;
  }

  for(int i=data.DragItems.Count - 1; i >= 0; i--)
  {
   ListViewItem newItem = (ListViewItem) data.DragItems[i];
   base.Items.Insert(hoverIndex, newItem);
  }
 }

 if(data.ListView != null)
 {
  foreach(ListViewItem itemToRemove in data.ListView.SelectedItems)
  {
   data.ListView.Items.Remove(itemToRemove);
  }
 }


 if(m_previousItem != null)
 {
  m_previousItem = null;
 }

 this.Invalidate();

 base.OnDragDrop (drgevent);

}

Known Problems

  • I've fixed all known problems so far.

Version History

  • May 17, 2004
    • Fixed inability to have lines shown for Large or Small Icon listings.
    • Fixed ability to fully move ListViewItems without losing data.
    • Removed hack to find the corresponding DragAndDropListView control.
  • May 14, 2004
    • Fixed ListView not scrolling.
    • Added AllowReorder to allow turning row reordering and row transfer off.
    • Added LineColor to allow you to set the color of the line drawn.
  • May 13, 2004
    • Initial launch showing functionality.

References

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

About the Author

Matt Hawley

United States United States
No Biography provided

Comments and Discussions

 
QuestionLicensing PinmemberMember 104455314-Dec-13 12:15 
QuestionMy vote is 5 Pinmemberpige28-Jun-13 1:36 
GeneralMy vote of 5 PinmemberPaul E. Bible27-Mar-13 4:23 
QuestionHow about Double Click support Pinmemberrewrewewrerw21-May-12 12:14 
BugJUMPY when doing drap drop Pinmemberrewrewewrerw21-May-12 12:12 
GeneralGet Drop Data PinmemberLaserson1-Oct-10 20:49 
GeneralLiscensing request Pinmembernickfas8-Jun-10 14:01 
GeneralRetaining tag or name property of item after drag-drop reorder Pinmemberhoncho2612-Jun-08 9:41 
GeneralFOUND THE ANSWER! Re: Retaining tag or name property of item after drag-drop reorder Pinmemberhoncho2612-Jun-08 10:45 
General"Jumping" at the bottom on drag and drop [FIX] - dragging down 2 nodes instead of one [FIX] Pinmemberpaintor11-Feb-08 1:37 
QuestionProblem with Sorting [modified] Pinmembershashank_15610-Feb-08 23:31 
GeneralBug Fix - When reordering down and horizontal scroll bar is visible PinmemberSteve Marshall29-Oct-07 6:25 
GeneralVB Code Pinmemberpowermetal1-Oct-07 8:19 
It took me to convert to VB about 3hs+, I'm newbie and think that this can help someone (I used some tools to convert the code but none of those work well, then I manually translate the code...)
 
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.Windows.Forms
Imports System.ComponentModel
 
namespace DragNDrop
 
Public Class DragAndDropListView
Inherits ListView
 
#Region "Private Members"
Private m_previousItem As ListViewItem
Private m_allowReorder As Boolean
Private m_lineColor As Color
#End Region
 
#Region "Public Properties"
 
_
Public Property AllowReorder() As Boolean
Get
Return m_allowReorder
End Get
Set(ByVal value As Boolean)
m_allowReorder = value
End Set
End Property
 
_
Public Property LineColor() As Color
Get
Return m_lineColor
End Get
Set(ByVal value As Color)
m_lineColor = value
End Set
End Property
#End Region
 
#Region "Protected and Public Methods"
Public Sub New()
MyBase.New()
m_allowReorder = True
m_lineColor = Color.Red
 
'Me.FullRowSelect = False
End Sub
 
Protected Overrides Sub OnDragDrop(ByVal drgevent As DragEventArgs)
If Not m_allowReorder Then
MyBase.OnDragDrop(drgevent)
Return
End If
 
' get the currently hovered row that the items will be dragged to
Dim clientPoint As Point = MyBase.PointToClient(New Point(drgevent.X, drgevent.Y))
Dim hoverItem As ListViewItem = MyBase.GetItemAt(clientPoint.X, clientPoint.Y)
 
If Not drgevent.Data.GetDataPresent(GetType(DragItemData).ToString()) OrElse _
(CType(drgevent.Data.GetData(GetType(DragItemData).ToString()), DragItemData)).ListView Is Nothing OrElse _
(CType(drgevent.Data.GetData(GetType(DragItemData).ToString()), DragItemData)).DragItems.Count = 0 Then Return
 
'retrieve the drag item data
Dim data As DragItemData = CType(drgevent.Data.GetData(GetType(DragItemData).ToString()), DragItemData)
 
If hoverItem Is Nothing Then
'the user does not wish to re-order the items, just append to the end
For i As Integer = 0 To data.DragItems.Count - 1
Dim newItem As ListViewItem = CType(data.DragItems(i), ListViewItem)
MyBase.Items.Add(newItem)
Next
Else
' the user wishes to re-order the items
 
' get the index of the hover item
Dim hoverIndex As Integer = hoverItem.Index
 
' determine if the items to be dropped are from
' this list view. If they are, perform a hack
' to increment the hover index so that the items
' get moved properly.
If Me Is data.ListView Then
If hoverIndex > MyBase.SelectedItems(0).Index Then
hoverIndex += 1
End If
End If
' insert the new items into the list view
' by inserting the items reversely from the array list
For i As Integer = data.DragItems.Count - 1 To 0 Step -1
Dim newItem As ListViewItem = CType(data.DragItems(i), ListViewItem)
MyBase.Items.Insert(hoverIndex, newItem)
Next
End If
 
' remove all the selected items from the previous list view
' if the list view was found
If data.ListView IsNot Nothing Then
For Each itemToRemove As ListViewItem In data.ListView.SelectedItems
data.ListView.Items.Remove(itemToRemove)
Next
End If
 
' set the back color of the previous item, then nullify it
If m_previousItem IsNot Nothing Then
m_previousItem = Nothing
End If
 
Me.Invalidate()
 
' call the base on drag drop to raise the event
MyBase.OnDragDrop(drgevent)
End Sub
 
Protected Overrides Sub OnDragOver(ByVal drgevent As DragEventArgs)
If Not m_allowReorder Then
MyBase.OnDragOver(drgevent)
Return
End If
 
If Not drgevent.Data.GetDataPresent(GetType(DragItemData).ToString()) Then
' the item(s) being dragged do not have any data associated
drgevent.Effect = DragDropEffects.None
Return
End If
 
If MyBase.Items.Count > 0 Then
' get the currently hovered row that the items will be dragged to
Dim clientPoint As Point = MyBase.PointToClient(New Point(drgevent.X, drgevent.Y))
Dim hoverItem As ListViewItem = MyBase.GetItemAt(clientPoint.X, clientPoint.Y)
 
Dim g As Graphics = Me.CreateGraphics()
 
If hoverItem Is Nothing Then
 
'MessageBox.Show(base.GetChildAtPoint(new Point(clientPoint.X, clientPoint.Y)).GetType().ToString());
 
' no item was found, so no drop should take place
drgevent.Effect = DragDropEffects.Move
 
If m_previousItem IsNot Nothing Then
m_previousItem = Nothing
Invalidate()
End If
 
hoverItem = MyBase.Items(MyBase.Items.Count - 1)
 
If Me.View = View.Details OrElse Me.View = View.List Then
g.DrawLine(New Pen(m_lineColor, 2), New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + hoverItem.Bounds.Height), New Point(hoverItem.Bounds.X + Me.Bounds.Width, hoverItem.Bounds.Y + hoverItem.Bounds.Height))
g.FillPolygon(New SolidBrush(m_lineColor), New Point() {New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5), New Point(hoverItem.Bounds.X + 5, hoverItem.Bounds.Y + hoverItem.Bounds.Height), New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + hoverItem.Bounds.Height + 5)})
g.FillPolygon(New SolidBrush(m_lineColor), New Point() {New Point(Me.Bounds.Width - 4, hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5), New Point(Me.Bounds.Width - 9, hoverItem.Bounds.Y + hoverItem.Bounds.Height), New Point(Me.Bounds.Width - 4, hoverItem.Bounds.Y + hoverItem.Bounds.Height + 5)})
Else
g.DrawLine(New Pen(m_lineColor, 2), New Point(hoverItem.Bounds.X + hoverItem.Bounds.Width, hoverItem.Bounds.Y), New Point(hoverItem.Bounds.X + hoverItem.Bounds.Width, hoverItem.Bounds.Y + hoverItem.Bounds.Height))
g.FillPolygon(New SolidBrush(m_lineColor), New Point() {New Point(hoverItem.Bounds.X + hoverItem.Bounds.Width - 5, hoverItem.Bounds.Y), New Point(hoverItem.Bounds.X + hoverItem.Bounds.Width + 5, hoverItem.Bounds.Y), New Point(hoverItem.Bounds.X + hoverItem.Bounds.Width, hoverItem.Bounds.Y + 5)})
g.FillPolygon(New SolidBrush(m_lineColor), New Point() {New Point(hoverItem.Bounds.X + hoverItem.Bounds.Width - 5, hoverItem.Bounds.Y + hoverItem.Bounds.Height), New Point(hoverItem.Bounds.X + hoverItem.Bounds.Width + 5, hoverItem.Bounds.Y + hoverItem.Bounds.Height), New Point(hoverItem.Bounds.X + hoverItem.Bounds.Width, hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5)})
End If
 
' call the base OnDragOver event
MyBase.OnDragOver(drgevent)
 
Return
End If
 
' determine if the user is currently hovering over a new
' item. If so, set the previous item's back color back
' to the default color.
If (m_previousItem IsNot Nothing AndAlso m_previousItem IsNot hoverItem) OrElse m_previousItem Is Nothing Then
Me.Invalidate()
End If
 
' set the background color of the item being hovered
' and assign the previous item to the item being hovered
'hoverItem.BackColor = Color.Beige;
m_previousItem = hoverItem
 
If Me.View = View.Details OrElse Me.View = View.List Then
g.DrawLine(New Pen(m_lineColor, 2), New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y), New Point(hoverItem.Bounds.X + Me.Bounds.Width, hoverItem.Bounds.Y))
g.FillPolygon(New SolidBrush(m_lineColor), New Point() {New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y - 5), New Point(hoverItem.Bounds.X + 5, hoverItem.Bounds.Y), New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + 5)})
g.FillPolygon(New SolidBrush(m_lineColor), New Point() {New Point(Me.Bounds.Width - 4, hoverItem.Bounds.Y - 5), New Point(Me.Bounds.Width - 9, hoverItem.Bounds.Y), New Point(Me.Bounds.Width - 4, hoverItem.Bounds.Y + 5)})
Else
g.DrawLine(New Pen(m_lineColor, 2), New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y), New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + hoverItem.Bounds.Height))
g.FillPolygon(New SolidBrush(m_lineColor), New Point() {New Point(hoverItem.Bounds.X - 5, hoverItem.Bounds.Y), New Point(hoverItem.Bounds.X + 5, hoverItem.Bounds.Y), New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + 5)})
g.FillPolygon(New SolidBrush(m_lineColor), New Point() {New Point(hoverItem.Bounds.X - 5, hoverItem.Bounds.Y + hoverItem.Bounds.Height), New Point(hoverItem.Bounds.X + 5, hoverItem.Bounds.Y + hoverItem.Bounds.Height), New Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + hoverItem.Bounds.Height - 5)})
' go through each of the selected items, and if any of the
' selected items have the same index as the item being
' hovered, disable dropping.
 
For Each itemToMove As ListViewItem In MyBase.SelectedItems
If itemToMove.Index = hoverItem.Index Then
drgevent.Effect = DragDropEffects.None
hoverItem.EnsureVisible()
Return
End If
Next
End If
' ensure that the hover item is visible
hoverItem.EnsureVisible()
End If
 
' everything is fine, allow the user to move the items
drgevent.Effect = DragDropEffects.Move
 
' call the base OnDragOver event
MyBase.OnDragOver(drgevent)
End Sub
 
Protected Overrides Sub OnDragEnter(ByVal drgevent As DragEventArgs)
If Not m_allowReorder Then
MyBase.OnDragEnter(drgevent)
Return
End If
 
If Not drgevent.Data.GetDataPresent(GetType(DragItemData).ToString()) Then
' the item(s) being dragged do not have any data associated
drgevent.Effect = DragDropEffects.None
Return
 
End If
 
' everything is fine, allow the user to move the items
drgevent.Effect = DragDropEffects.Move
 
' call the base OnDragEnter event
MyBase.OnDragEnter(drgevent)
 
End Sub
 
Protected Overrides Sub OnItemDrag(ByVal e As ItemDragEventArgs)
If Not m_allowReorder Then
MyBase.OnItemDrag(e)
Return
End If
 
' call the DoDragDrop method
MyBase.DoDragDrop(GetDataForDragDrop(), DragDropEffects.Move)
 
' call the base OnItemDrag event
MyBase.OnItemDrag(e)
End Sub
 
Protected Overrides Sub OnLostFocus(ByVal e As EventArgs)
' reset the selected items background and remove the previous item
ResetOutOfRange()
 
Invalidate()
 
' call the OnLostFocus event
MyBase.OnLostFocus(e)
End Sub
 
Protected Overrides Sub OnDragLeave(ByVal e As EventArgs)
' reset the selected items background and remove the previous item
ResetOutOfRange()
 
Invalidate()
 
' call the base OnDragLeave event
MyBase.OnDragLeave(e)
End Sub
 
#Region "Private Methods"
Private Function GetDataForDragDrop() As DragItemData
' create a drag item data object that will be used to pass along with the drag and drop
Dim data As DragItemData = New DragItemData(Me)
 
' go through each of the selected items and
' add them to the drag items collection
' by creating a clone of the list item
 
For Each item As ListViewItem In Me.SelectedItems
data.DragItems.Add(item.Clone())
Next
 
Return data
End Function
 
Private Sub ResetOutOfRange()
' determine if the previous item exists,
' if it does, reset the background and release
' the previous item
If m_previousItem IsNot Nothing Then
m_previousItem = Nothing
End If
End Sub
 
#End Region
 

#End Region
 
#Region "DragItemData Class"
Private Class DragItemData
 
#Region "Private Members"
Private m_listView As DragAndDropListView
Private m_dragItems As ArrayList
#End Region
 
#Region "Public Properties"
 
Public ReadOnly Property ListView() As DragAndDropListView
Get
Return m_listView
End Get
End Property
 
Public ReadOnly Property DragItems() As ArrayList
Get
Return m_dragItems
End Get
End Property
 
#End Region
 
#Region "Public Methods and Implementation"
Public Sub New(ByVal listView As DragAndDropListView)
m_listView = listView
m_dragItems = New ArrayList()
End Sub
#End Region
 
End Class
#End Region
 
End Class
 
END NAMESPACE

GeneralBug Fix for LargeIcon or SmallIcon view Pinmemberhuanyi25-Sep-07 3:02 
GeneralRe: Bug Fix for LargeIcon or SmallIcon view Pinmembernullesc19-Nov-08 17:24 
GeneralDrag&Drop only inside of current List PinmemberMichaZ1238-Aug-07 0:30 
GeneralQuestion Pinmemberloneferret17-Jul-06 12:02 
QuestionLicensing Pinmembermark_ledwich20-Apr-06 19:44 
QuestionView LargeIcon ? Pinmembermiha527-Nov-05 22:59 
QuestionFlicker when dragging Pinsussdgannon3416-Sep-05 18:16 
Questionhow to implement drag and drop in the asp.net page ,like list data or multiple select from one to another PinmemberJade_king15-Sep-05 22:13 
GeneralListViewItem Image problem Pinmemberdidis1-Dec-04 5:24 
GeneralRe: ListViewItem Image problem PinmemberDiego F.3-Apr-07 4:30 
GeneralAllow both items drag &amp; drop and files drag &amp; drop PinsussBertrand Dunogier3-Oct-04 2:35 
GeneralRe: Allow both items drag &amp; drop and files drag &amp; drop PinmemberCraig Nagy1-Mar-05 18:37 
GeneralRe: Allow both items drag &amp; drop and files drag &amp; drop PinmemberChris Cocker5-Apr-05 4:29 
Generalgreat control, 2 questions Pinmembercmac24-Aug-04 2:41 
GeneralRe: great control, 2 questions PinmemberJames Pepin8-Jun-05 5:47 
GeneralEnhancement/bug fix for List/Details PinmemberRichard Birkby22-Jul-04 23:17 
GeneralThankyou PinmemberRichard Birkby19-Jul-04 23:00 

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 | Mobile
Web03 | 2.8.140721.1 | Last Updated 13 May 2004
Article Copyright 2004 by Matt Hawley
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid