|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace ListViewCustomReorder
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Important:
// Right now it's not possible to drag more than one LVItem, so make sure the LV is in single selection mode
listView1.MultiSelect = false;
}
private void Form1_Load(object sender, EventArgs e)
{
// Fill the LV with test values
for (int i = 0; i < 20; i++)
{
ListViewItem it = new ListViewItem("Item " + i);
it.SubItems.Add("Item " + i + "-1");
it.SubItems.Add("Item " + i + "-2");
it.SubItems.Add("Item " + i + "-3");
listView1.Items.Add(it);
}
}
// The LVItem being dragged
private ListViewItem _itemDnD = null;
private void listView1_MouseDown(object sender, MouseEventArgs e)
{
_itemDnD = listView1.GetItemAt(e.X, e.Y);
// if the LV is still empty, no item will be found anyway, so we don't have to consider this case
}
private void listView1_MouseMove(object sender, MouseEventArgs e)
{
if (_itemDnD == null)
return;
// Show the user that a drag operation is happening
Cursor = Cursors.Hand;
// calculate the bottom of the last item in the LV so that you don't have to stop your drag at the last item
int lastItemBottom = Math.Min(e.Y, listView1.Items[listView1.Items.Count-1].GetBounds(ItemBoundsPortion.Entire).Bottom-1);
// use 0 instead of e.X so that you don't have to keep inside the columns while dragging
ListViewItem itemOver = listView1.GetItemAt(0, lastItemBottom);
if (itemOver == null)
return;
Rectangle rc = itemOver.GetBounds(ItemBoundsPortion.Entire);
if (e.Y < rc.Top + (rc.Height / 2))
{
listView1.LineBefore = itemOver.Index;
listView1.LineAfter = -1;
}
else
{
listView1.LineBefore = -1;
listView1.LineAfter = itemOver.Index;
}
// invalidate the LV so that the insertion line is shown
listView1.Invalidate();
}
private void listView1_MouseUp(object sender, MouseEventArgs e)
{
if (_itemDnD == null)
return;
try
{
// calculate the bottom of the last item in the LV so that you don't have to stop your drag at the last item
int lastItemBottom = Math.Min(e.Y, listView1.Items[listView1.Items.Count - 1].GetBounds(ItemBoundsPortion.Entire).Bottom - 1);
// use 0 instead of e.X so that you don't have to keep inside the columns while dragging
ListViewItem itemOver = listView1.GetItemAt(0, lastItemBottom);
if (itemOver == null)
return;
Rectangle rc = itemOver.GetBounds(ItemBoundsPortion.Entire);
// find out if we insert before or after the item the mouse is over
bool insertBefore;
if (e.Y < rc.Top + (rc.Height / 2))
{
insertBefore = true;
}
else
{
insertBefore = false;
}
if (_itemDnD != itemOver) // if we dropped the item on itself, nothing is to be done
{
if (insertBefore)
{
listView1.Items.Remove(_itemDnD);
listView1.Items.Insert(itemOver.Index, _itemDnD);
}
else
{
listView1.Items.Remove(_itemDnD);
listView1.Items.Insert(itemOver.Index + 1, _itemDnD);
}
}
// clear the insertion line
listView1.LineAfter =
listView1.LineBefore = -1;
listView1.Invalidate();
}
finally
{
// finish drag&drop operation
_itemDnD = null;
Cursor = Cursors.Default;
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.