|
|
Comments and Discussions
|
|
 |
|

|
Thank you so much for this article, Can someone please help me with some new feature to add to this and make it aweosome: Adding Double Click support to this. So users be able to move items also by double-clicking on them.
Thanks all.
|
|
|
|

|
Great article, thank you for sharing it But still one annoying thing:
when we want to drag-drop between too list views, while the item is being dragged the line indicator JUMPS to the last item of the drag source... How can we prevent it from doing this jump?
|
|
|
|

|
Hi, thanks for this control!
But i have a question - how to get a name of listview item (that was dragged) from target listview?
Thanks.
|
|
|
|

|
I too would like to use this code in commercial software. What are your terms for licensing?
|
|
|
|

|
Hello!
I'm trying to use the DragNDropListView for a data-driven list. Since there is no key property for a ListViewItem like you might find in a dropdown listbox, I need to store the underlying data key in some other property. I've been saving it in either the Tag or Name property of each item.
However, when using the DragNDropListView control, after dragging an item, it's tag and name properties are blank. I have looked through the source code at where items are created, and my only guess is that when it inserts items back into the listview after a drag, only the textual identifier of the ListViewItem is retained. I've tried to set the .tag and .name properties of the item before it is inserted, but to no avail.
Can anyone make a recommendation on how to tweak the code so that my underlying data key is retained through a drag-drop operation?
Rich Gunther
rich@ovostudios.com
|
|
|
|

|
I was recieving a jumping of the selector when dragging downward. This appeared to be related to the dragging over the horizontal scrollbar. I fixed this by detecting if the jump should be applied or not (not tested for multiple listviews)
private const int WS_HSCROLL = 0x100000;
private const int GWL_STYLE = (-16);
[DllImport("user32", CharSet=CharSet.Auto)]
private static extern int GetWindowLong(IntPtr hwnd, int nIndex);
private bool IsHorizontalScrollBarVisible()
{
if (!this.IsHandleCreated)
return false;
return (GetWindowLong(this.Handle, GWL_STYLE) & WS_HSCROLL) != 0;
}
will detect if the scrollbar is present, and in OnDragOver() before the call to CreateGraphics
if( hoverItem == null )
{
if ( IsHorizontalScrollBarVisible() )
{
// added 2 px to scrollbar to avoid jump in gutter
hoverItem = base.GetItemAt(clientPoint.X, clientPoint.Y -
SystemInformation.HorizontalScrollBarHeight + 2 );
if( hoverItem != null )
{
if ( hoverItem.Index == this.Items.Count - 1 )
{
// found the last one, we want to drop at the bottom
hoverItem = null;
}
else
{
this.EnsureVisible( hoverItem.Index + 1 );
}
}
}
}
This works for horizontal scrollbar visible or not, with arbritrary vertical scrollbar.
Additionally I found the dragging down counter intuitive as it dropped an item 2 nodes below instead of "in the middle" where the selector was (due to the line being at the top of each node). I therefore took out the code below from OnDragDrop()
// 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(this == data.ListView)
// {
// if(hoverIndex > base.SelectedItems[0].Index)
// hoverIndex++;
//}
Please note these alterations are not tested on multiple list boxes
|
|
|
|

|
Hi
Thanks for creating such an useful control.
I have come across a serious problem while using it.
it works fine until the sorting property is set to none.but when i change it to ascending or descending,the drag and drop WITHIN the same listview does not work.
i works fine if i drag an item from one list view and drop it to another.
Anyone has the solution ? pls reply
modified on Monday, February 11, 2008 6:09 AM
|
|
|
|

|
When the horizontal scroll bar is visible and the display rectangle for the listview is a couple of pixles smaller than N complete items, you cannot drag an item down the list... To fix this you need to add an extra if statement to the OnDragOver() method. Add the following after the call to GetItemAt(clientPoint.X, clientPoint.Y) but before CreateGraphics(). <code> // If we are trying to scroll down, we might be stuck on the horizontal scroll bar, get the // item and scroll the next item into view. if( hoverItem == null ) { hoverItem = base.GetItemAt(clientPoint.X, clientPoint.Y - SystemInformation.HorizontalScrollBarHeight ); if( hoverItem != null ) { this.EnsureVisible( hoverItem.Index + 1 ); } } </code>
|
|
|
|

|
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
|
|
|
|

|
It works very well but in LargeIcon or SmallIcon
I do some fix in DragAndDropListView.cs as below
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.ComponentModel;
namespace DragNDrop
{
public class DragAndDropListView : ListView
{
#region Private Members
private ListViewItem m_previousItem;
private bool m_allowReorder;
private Color m_lineColor;
#endregion
#region Public Properties
[Category("Behavior")]
public bool AllowReorder
{
get { return m_allowReorder; }
set { m_allowReorder = value; }
}
[Category("Appearance")]
public Color LineColor
{
get { return m_lineColor; }
set { m_lineColor = value; }
}
#endregion
#region Protected and Public Methods
public DragAndDropListView()
: base()
{
m_allowReorder = true;
m_lineColor = Color.Black;
}
protected override void OnDragDrop(DragEventArgs drgevent)
{
if (!m_allowReorder)
{
base.OnDragDrop(drgevent);
return;
}
// get the currently hovered row that the items will be dragged to
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;
// retrieve the drag item data
DragItemData data = (DragItemData)drgevent.Data.GetData(typeof(DragItemData).ToString());
if (hoverItem == null)
{
// the user does not wish to re-order the items, just append to the end
for (int i = 0; i < data.DragItems.Count; i++)
{
ListViewItem newItem = (ListViewItem)data.DragItems[i];
base.Items.Add(newItem);
}
}
else
{
// the user wishes to re-order the items
// get the index of the hover item
int hoverIndex = 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 (this == data.ListView)
{
if (base.SelectedItems[0].Index <= hoverIndex && hoverIndex <= base.SelectedItems[base.SelectedItems.Count - 1].Index + 1)
{
if (m_previousItem != null)
{
m_previousItem = null;
}
this.Invalidate();
// call the base on drag drop to raise the event
base.OnDragDrop(drgevent);
return;
}
//else if (hoverIndex > base.SelectedItems[0].Index)
// hoverIndex += base.SelectedItems.Count;
}
// insert the new items into the list view
// by inserting the items reversely from the array list
for (int i = data.DragItems.Count - 1; i >= 0; i--)
{
ListViewItem newItem = (ListViewItem)data.DragItems[i];
base.Items.Insert(hoverIndex, newItem);
base.Items[hoverIndex].Position = base.Items[hoverIndex + 1].Position;
}
}
// remove all the selected items from the previous list view
// if the list view was found
if (data.ListView != null)
{
foreach (ListViewItem itemToRemove in data.ListView.SelectedItems)
{
data.ListView.Items.Remove(itemToRemove);
}
}
//this.ArrangeIcons();
//this.
//this.Sorting = SortOrder.Ascending;
//this.Sort();
//base.AutoArrange = true;
//base.Refresh();
//this.ArrangeIcons();
this.Refresh();
//this.ArrangeIcons();
//this.RedrawItems(0, base.Items.Count - 1, false);
// set the back color of the previous item, then nullify it
if (m_previousItem != null)
{
m_previousItem = null;
}
this.Invalidate();
// call the base on drag drop to raise the event
base.OnDragDrop(drgevent);
}
protected override void OnDragOver(DragEventArgs drgevent)
{
if (!m_allowReorder)
{
base.OnDragOver(drgevent);
return;
}
if (!drgevent.Data.GetDataPresent(typeof(DragItemData).ToString()))
{
// the item(s) being dragged do not have any data associated
drgevent.Effect = DragDropEffects.None;
return;
}
if (base.Items.Count > 0)
{
// get the currently hovered row that the items will be dragged to
Point clientPoint = base.PointToClient(new Point(drgevent.X, drgevent.Y));
ListViewItem lastItem = base.Items[base.Items.Count - 1];
Point ptLastItem = new Point(lastItem.Bounds.X + lastItem.Bounds.Width + lastItem.Bounds.X, lastItem.Bounds.Y + lastItem.Bounds.Height);
ListViewItem hoverItem = base.GetItemAt(clientPoint.X, clientPoint.Y);
Graphics g = this.CreateGraphics();
if (hoverItem == null && (clientPoint.X > ptLastItem.X || clientPoint.Y > ptLastItem.Y))
{
//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 != 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 - 3, hoverItem.Bounds.Y), new Point(hoverItem.Bounds.X + hoverItem.Bounds.Width + 3, hoverItem.Bounds.Y), new Point(hoverItem.Bounds.X + hoverItem.Bounds.Width, hoverItem.Bounds.Y + 3) });
g.FillPolygon(new SolidBrush(m_lineColor), new Point[] { new Point(hoverItem.Bounds.X + hoverItem.Bounds.Width - 4, hoverItem.Bounds.Y + hoverItem.Bounds.Height), new Point(hoverItem.Bounds.X + hoverItem.Bounds.Width + 4, hoverItem.Bounds.Y + hoverItem.Bounds.Height), new Point(hoverItem.Bounds.X + hoverItem.Bounds.Width, hoverItem.Bounds.Y + hoverItem.Bounds.Height - 4) });
}
// call the base OnDragOver event
base.OnDragOver(drgevent);
return;
}
// 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 != null && m_previousItem != hoverItem) || m_previousItem == null)
{
this.Invalidate();
}
// 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 (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 /*+ 2 *hoverItem.Bounds.Height*/));
//g.FillPolygon(new SolidBrush(m_lineColor), new Point[] { new Point(hoverItem.Bounds.X, hoverItem.Bounds.Y - 3 + hoverItem.Bounds.Height), new Point(hoverItem.Bounds.X + 3, hoverItem.Bounds.Y + hoverItem.Bounds.Height), new Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + 3 + hoverItem.Bounds.Height) });
//g.FillPolygon(new SolidBrush(m_lineColor), new Point[] { new Point(this.Bounds.Width - 4, hoverItem.Bounds.Y - 4 + hoverItem.Bounds.Height), new Point(this.Bounds.Width - 9, hoverItem.Bounds.Y + hoverItem.Bounds.Height -1 ), new Point(this.Bounds.Width - 4, hoverItem.Bounds.Y + 3 + hoverItem.Bounds.Height -1) });
}
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 - 3, hoverItem.Bounds.Y), new Point(hoverItem.Bounds.X + 3, hoverItem.Bounds.Y), new Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + 3) });
g.FillPolygon(new SolidBrush(m_lineColor), new Point[] { new Point(hoverItem.Bounds.X - 4, hoverItem.Bounds.Y + hoverItem.Bounds.Height), new Point(hoverItem.Bounds.X + 4, hoverItem.Bounds.Y + hoverItem.Bounds.Height), new Point(hoverItem.Bounds.X, hoverItem.Bounds.Y + hoverItem.Bounds.Height - 4) });
}
// 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.
foreach (ListViewItem itemToMove in base.SelectedItems)
{
if (itemToMove.Index == hoverItem.Index)
{
drgevent.Effect = DragDropEffects.None;
hoverItem.EnsureVisible();
return;
}
}
// ensure that the hover item is visible
hoverItem.EnsureVisible();
}
// everything is fine, allow the user to move the items
drgevent.Effect = DragDropEffects.Move;
// call the base OnDragOver event
base.OnDragOver(drgevent);
}
protected override void OnDragEnter(DragEventArgs drgevent)
{
if (!m_allowReorder)
{
base.OnDragEnter(drgevent);
return;
}
if (!drgevent.Data.GetDataPresent(typeof(DragItemData).ToString()))
{
// the item(s) being dragged do not have any data associated
drgevent.Effect = DragDropEffects.None;
return;
}
// everything is fine, allow the user to move the items
drgevent.Effect = DragDropEffects.Move;
// call the base OnDragEnter event
base.OnDragEnter(drgevent);
}
protected override void OnItemDrag(ItemDragEventArgs e)
{
if (!m_allowReorder)
{
base.OnItemDrag(e);
return;
}
// call the DoDragDrop method
base.DoDragDrop(GetDataForDragDrop(), DragDropEffects.Move);
// call the base OnItemDrag event
base.OnItemDrag(e);
}
protected override void OnLostFocus(EventArgs e)
{
// reset the selected items background and remove the previous item
ResetOutOfRange();
Invalidate();
// call the OnLostFocus event
base.OnLostFocus(e);
}
protected override void OnDragLeave(EventArgs e)
{
// reset the selected items background and remove the previous item
ResetOutOfRange();
Invalidate();
// call the base OnDragLeave event
base.OnDragLeave(e);
}
#endregion
#region Private Methods
private DragItemData GetDataForDragDrop()
{
// create a drag item data object that will be used to pass along with the drag and drop
DragItemData data = new DragItemData(this);
// go through each of the selected items and
// add them to the drag items collection
// by creating a clone of the list item
foreach (ListViewItem item in this.SelectedItems)
{
data.DragItems.Add(item.Clone());
}
return data;
}
private void ResetOutOfRange()
{
// determine if the previous item exists,
// if it does, reset the background and release
// the previous item
if (m_previousItem != null)
{
m_previousItem = null;
}
}
#endregion
#region DragItemData Class
private class DragItemData
{
#region Private Members
private DragAndDropListView m_listView;
private ArrayList m_dragItems;
#endregion
#region Public Properties
public DragAndDropListView ListView
{
get { return m_listView; }
}
public ArrayList DragItems
{
get { return m_dragItems; }
}
#endregion
#region Public Methods and Implementation
public DragItemData(DragAndDropListView listView)
{
m_listView = listView;
m_dragItems = new ArrayList();
}
#endregion
}
#endregion
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
}
}
|
|
|
|

|
Hello!
I am newbie to C#.
The problem is:
I have two Drag and Drop List Views in my form.
1.Dragging and dropping from one list to another should not be allowed.I mean,I should only allow dragging and dropping for List1 elements only in List1. How to do this?
2.Can I dinamically change the List element attributes when the dragged list element is dropped? How to do this?
3.How to sort the List by one element attribute? Currently I am working with XML. So I fetch the data from XML into a List, perform sorting by writing own comparer and only after then load the Drag And Drop List View with sorted data. Maybe there is an easier way?
3.How to retrieve current Drag And Drop List View with all elements in order how they are displayed.
Thanks Everyone!
Misha
|
|
|
|

|
Just let me say that I love your code. Good comments and easy to follow.
Now for my question.
I would need to have one of the listviews to have 3rd column (which I can do) with permanent information in it. Such as row 1, row 2 etc.
So as when you drag a selection from one listview (the one with only 2 columns) to the other
(the one with the row count) the row count stays in the first column and the other two are inserted.
GOD, I hope i'm explaining myself correctly... lol I may be long-winded here, just want to make sure someone understands me...
So...
listview #1 has:
list1 | item 1
listview #2 has:
row 1 | |
When dragging from list 1 over to 2 it displays
row 1 | list1 | item1
Hope this is clear.. been busting my back-side over this, would really need some help on this one.
Really...
Thank you for any help..
LoneFerret
Cross my heart, smack me dead...stick a lobster on my head.
|
|
|
|

|
This is a great control and its exactly what i need. Can I use it in comercial code(recognition will be given in the design document)?
|
|
|
|

|
Hi,
When I use your component, and if ListView.View = LargeIcon
then item reorder - did not work.
Any idea to solve this problem ?
|
|
|
|

|
This is exactly what I needed, thanks! Only problem I have is hideous flicker when dragging. I've tried a few different things, but with no success. Any ideas?
|
|
|
|
|

|
Hi,
When I use your component, and if i have setup the image list property.
The image appear on the left of the listviewitem ... and disappear after a drag&drop.
Any idea to solve this problem ?
Didier.
|
|
|
|

|
First, let me thank you for your control, it's quite amazing.
Now my problem is that I'd still like to allow external files drag & dropping to one of my listviews, while still allowing items reordering. When I drag a file over my listview, the DragEnter even is not even called. If I disable AllowReorder, everything works fine.
What can I do to enable both at the same time ?
Thanks in advance.
|
|
|
|

|
1. you cant drag items from a standard listview, only from dragndrop control
2. it appears that the listview items when dragged down the listview, are added one extra line down, but when dragging up everything works fine.
|
|
|
|

|
In the OnDragOver event handler, the drawing of the horizontal line and triangles takes place.
When the scrollbar is displayed, the right hand triangle is drawn underneath the scrollbar. To correct this, you need to use ClientSize.Width, rather than the width of the hoverItem when drawing the line and triangle.
You can also use hoverItem.Bounds.Bottom rather than adding the Y+Height together - it makes the code a little simpler!
In addition, it's usually a good idea to Dispose of Brushes and Pens as soon as you've used them. This is easily done by wrapping them in a using() statement.
Apart from this - it's worked perfectly.
Thanks.
|
|
|
|

|
It works brilliantly. Thanks!
One thing to remember - in case you are in the habit of subclassing ListItem and adding the subclass to the ListView (giving you a nice bit of polymorphism), you will need to override the Clone() method, cloning any data you store in the subclass. Also remember to provide a public, parameterless constructor to your subclass.
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Drag and Drop list items within list views or to other list views without manual intervention.
| Type | Article |
| Licence | |
| First Posted | 12 May 2004 |
| Views | 126,417 |
| Bookmarked | 85 times |
|
|