How to: Display an Insertion Mark in a Windows Forms ListView Control
The insertion mark in the ListView control shows users the point where dragged items will be inserted. When a user drags an item to a point between two other items, the insertion mark shows the item's expected new location.
Note |
---|
The insertion mark feature is available only on Windows XP Home Edition, Windows XP Professional, Windows Server 2003 when your application calls the System.Windows.Forms.Application.EnableVisualStyles method. On earlier operating systems, any code relating to the insertion mark has no effect and the insertion mark will not appear. For more information, see ListViewInsertionMark. |
The following image shows an insertion mark:
The following code example demonstrates how to use this feature.
Example
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Public Class ListViewInsertionMarkExample
Inherits Form
Private myListView As ListView
Public Sub New()
' Initialize myListView.
myListView = New ListView()
myListView.Dock = DockStyle.Fill
myListView.View = View.LargeIcon
myListView.MultiSelect = False
myListView.ListViewItemSorter = New ListViewIndexComparer()
' Initialize the insertion mark.
myListView.InsertionMark.Color = Color.Green
' Add items to myListView.
myListView.Items.Add("zero")
myListView.Items.Add("one")
myListView.Items.Add("two")
myListView.Items.Add("three")
myListView.Items.Add("four")
myListView.Items.Add("five")
' Initialize the drag-and-drop operation when running
' under Windows XP or a later operating system.
If OSFeature.Feature.IsPresent(OSFeature.Themes)
myListView.AllowDrop = True
AddHandler myListView.ItemDrag, AddressOf myListView_ItemDrag
AddHandler myListView.DragEnter, AddressOf myListView_DragEnter
AddHandler myListView.DragOver, AddressOf myListView_DragOver
AddHandler myListView.DragLeave, AddressOf myListView_DragLeave
AddHandler myListView.DragDrop, AddressOf myListView_DragDrop
End If
' Initialize the form.
Me.Text = "ListView Insertion Mark Example"
Me.Controls.Add(myListView)
End Sub 'New
<STAThread()> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New ListViewInsertionMarkExample())
End Sub 'Main
' Starts the drag-and-drop operation when an item is dragged.
Private Sub myListView_ItemDrag(sender As Object, e As ItemDragEventArgs)
myListView.DoDragDrop(e.Item, DragDropEffects.Move)
End Sub 'myListView_ItemDrag
' Sets the target drop effect.
Private Sub myListView_DragEnter(sender As Object, e As DragEventArgs)
e.Effect = e.AllowedEffect
End Sub 'myListView_DragEnter
' Moves the insertion mark as the item is dragged.
Private Sub myListView_DragOver(sender As Object, e As DragEventArgs)
' Retrieve the client coordinates of the mouse pointer.
Dim targetPoint As Point = myListView.PointToClient(New Point(e.X, e.Y))
' Retrieve the index of the item closest to the mouse pointer.
Dim targetIndex As Integer = _
myListView.InsertionMark.NearestIndex(targetPoint)
' Confirm that the mouse pointer is not over the dragged item.
If targetIndex > -1 Then
' Determine whether the mouse pointer is to the left or
' the right of the midpoint of the closest item and set
' the InsertionMark.AppearsAfterItem property accordingly.
Dim itemBounds As Rectangle = myListView.GetItemRect(targetIndex)
If targetPoint.X > itemBounds.Left + (itemBounds.Width / 2) Then
myListView.InsertionMark.AppearsAfterItem = True
Else
myListView.InsertionMark.AppearsAfterItem = False
End If
End If
' Set the location of the insertion mark. If the mouse is
' over the dragged item, the targetIndex value is -1 and
' the insertion mark disappears.
myListView.InsertionMark.Index = targetIndex
End Sub 'myListView_DragOver
' Removes the insertion mark when the mouse leaves the control.
Private Sub myListView_DragLeave(sender As Object, e As EventArgs)
myListView.InsertionMark.Index = -1
End Sub 'myListView_DragLeave
' Moves the item to the location of the insertion mark.
Private Sub myListView_DragDrop(sender As Object, e As DragEventArgs)
' Retrieve the index of the insertion mark;
Dim targetIndex As Integer = myListView.InsertionMark.Index
' If the insertion mark is not visible, exit the method.
If targetIndex = -1 Then
Return
End If
' If the insertion mark is to the right of the item with
' the corresponding index, increment the target index.
If myListView.InsertionMark.AppearsAfterItem Then
targetIndex += 1
End If
' Retrieve the dragged item.
Dim draggedItem As ListViewItem = _
CType(e.Data.GetData(GetType(ListViewItem)), ListViewItem)
' Insert a copy of the dragged item at the target index.
' A copy must be inserted before the original item is removed
' to preserve item index values.
myListView.Items.Insert(targetIndex, _
CType(draggedItem.Clone(), ListViewItem))
' Remove the original copy of the dragged item.
myListView.Items.Remove(draggedItem)
End Sub 'myListView_DragDrop
' Sorts ListViewItem objects by index.
Private Class ListViewIndexComparer
Implements System.Collections.IComparer
Public Function Compare(x As Object, y As Object) As Integer _
Implements System.Collections.IComparer.Compare
Return CType(x, ListViewItem).Index - CType(y, ListViewItem).Index
End Function 'Compare
End Class 'ListViewIndexComparer
End Class 'ListViewInsertionMarkExample
using System;
using System.Drawing;
using System.Windows.Forms;
public class ListViewInsertionMarkExample : Form
{
private ListView myListView;
public ListViewInsertionMarkExample()
{
// Initialize myListView.
myListView = new ListView();
myListView.Dock = DockStyle.Fill;
myListView.View = View.LargeIcon;
myListView.MultiSelect = false;
myListView.ListViewItemSorter = new ListViewIndexComparer();
// Initialize the insertion mark.
myListView.InsertionMark.Color = Color.Green;
// Add items to myListView.
myListView.Items.Add("zero");
myListView.Items.Add("one");
myListView.Items.Add("two");
myListView.Items.Add("three");
myListView.Items.Add("four");
myListView.Items.Add("five");
// Initialize the drag-and-drop operation when running
// under Windows XP or a later operating system.
if (OSFeature.Feature.IsPresent(OSFeature.Themes))
{
myListView.AllowDrop = true;
myListView.ItemDrag += new ItemDragEventHandler(myListView_ItemDrag);
myListView.DragEnter += new DragEventHandler(myListView_DragEnter);
myListView.DragOver += new DragEventHandler(myListView_DragOver);
myListView.DragLeave += new EventHandler(myListView_DragLeave);
myListView.DragDrop += new DragEventHandler(myListView_DragDrop);
}
// Initialize the form.
this.Text = "ListView Insertion Mark Example";
this.Controls.Add(myListView);
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new ListViewInsertionMarkExample());
}
// Starts the drag-and-drop operation when an item is dragged.
private void myListView_ItemDrag(object sender, ItemDragEventArgs e)
{
myListView.DoDragDrop(e.Item, DragDropEffects.Move);
}
// Sets the target drop effect.
private void myListView_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.AllowedEffect;
}
// Moves the insertion mark as the item is dragged.
private void myListView_DragOver(object sender, DragEventArgs e)
{
// Retrieve the client coordinates of the mouse pointer.
Point targetPoint =
myListView.PointToClient(new Point(e.X, e.Y));
// Retrieve the index of the item closest to the mouse pointer.
int targetIndex = myListView.InsertionMark.NearestIndex(targetPoint);
// Confirm that the mouse pointer is not over the dragged item.
if (targetIndex > -1)
{
// Determine whether the mouse pointer is to the left or
// the right of the midpoint of the closest item and set
// the InsertionMark.AppearsAfterItem property accordingly.
Rectangle itemBounds = myListView.GetItemRect(targetIndex);
if ( targetPoint.X > itemBounds.Left + (itemBounds.Width / 2) )
{
myListView.InsertionMark.AppearsAfterItem = true;
}
else
{
myListView.InsertionMark.AppearsAfterItem = false;
}
}
// Set the location of the insertion mark. If the mouse is
// over the dragged item, the targetIndex value is -1 and
// the insertion mark disappears.
myListView.InsertionMark.Index = targetIndex;
}
// Removes the insertion mark when the mouse leaves the control.
private void myListView_DragLeave(object sender, EventArgs e)
{
myListView.InsertionMark.Index = -1;
}
// Moves the item to the location of the insertion mark.
private void myListView_DragDrop(object sender, DragEventArgs e)
{
// Retrieve the index of the insertion mark;
int targetIndex = myListView.InsertionMark.Index;
// If the insertion mark is not visible, exit the method.
if (targetIndex == -1)
{
return;
}
// If the insertion mark is to the right of the item with
// the corresponding index, increment the target index.
if (myListView.InsertionMark.AppearsAfterItem)
{
targetIndex++;
}
// Retrieve the dragged item.
ListViewItem draggedItem =
(ListViewItem)e.Data.GetData(typeof(ListViewItem));
// Insert a copy of the dragged item at the target index.
// A copy must be inserted before the original item is removed
// to preserve item index values.
myListView.Items.Insert(
targetIndex, (ListViewItem)draggedItem.Clone());
// Remove the original copy of the dragged item.
myListView.Items.Remove(draggedItem);
}
// Sorts ListViewItem objects by index.
private class ListViewIndexComparer : System.Collections.IComparer
{
public int Compare(object x, object y)
{
return ((ListViewItem)x).Index - ((ListViewItem)y).Index;
}
}
}
#using <System.dll>
#using <System.Windows.Forms.dll>
#using <System.Drawing.dll>
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
public ref class ListViewInsertionMarkExample: public Form
{
private:
ListView^ myListView;
public:
ListViewInsertionMarkExample()
{
// Initialize myListView.
myListView = gcnew ListView;
myListView->Dock = DockStyle::Fill;
myListView->View = View::LargeIcon;
myListView->MultiSelect = false;
myListView->ListViewItemSorter = gcnew ListViewIndexComparer;
// Initialize the insertion mark.
myListView->InsertionMark->Color = Color::Green;
// Add items to myListView.
myListView->Items->Add( "zero" );
myListView->Items->Add( "one" );
myListView->Items->Add( "two" );
myListView->Items->Add( "three" );
myListView->Items->Add( "four" );
myListView->Items->Add( "five" );
// Initialize the drag-and-drop operation when running
// under Windows XP or a later operating system.
if ( System::Environment::OSVersion->Version->Major > 5 || (System::Environment::OSVersion->Version->Major == 5 && System::Environment::OSVersion->Version->Minor >= 1) )
{
myListView->AllowDrop = true;
myListView->ItemDrag += gcnew ItemDragEventHandler( this, &ListViewInsertionMarkExample::myListView_ItemDrag );
myListView->DragEnter += gcnew DragEventHandler( this, &ListViewInsertionMarkExample::myListView_DragEnter );
myListView->DragOver += gcnew DragEventHandler( this, &ListViewInsertionMarkExample::myListView_DragOver );
myListView->DragLeave += gcnew EventHandler( this, &ListViewInsertionMarkExample::myListView_DragLeave );
myListView->DragDrop += gcnew DragEventHandler( this, &ListViewInsertionMarkExample::myListView_DragDrop );
}
// Initialize the form.
this->Text = "ListView Insertion Mark Example";
this->Controls->Add( myListView );
}
private:
// Starts the drag-and-drop operation when an item is dragged.
void myListView_ItemDrag( Object^ /*sender*/, ItemDragEventArgs^ e )
{
myListView->DoDragDrop( e->Item, DragDropEffects::Move );
}
// Sets the target drop effect.
void myListView_DragEnter( Object^ /*sender*/, DragEventArgs^ e )
{
e->Effect = e->AllowedEffect;
}
// Moves the insertion mark as the item is dragged.
void myListView_DragOver( Object^ /*sender*/, DragEventArgs^ e )
{
// Retrieve the client coordinates of the mouse pointer.
Point targetPoint = myListView->PointToClient( Point(e->X,e->Y) );
// Retrieve the index of the item closest to the mouse pointer.
int targetIndex = myListView->InsertionMark->NearestIndex( targetPoint );
// Confirm that the mouse pointer is not over the dragged item.
if ( targetIndex > -1 )
{
// Determine whether the mouse pointer is to the left or
// the right of the midpoint of the closest item and set
// the InsertionMark.AppearsAfterItem property accordingly.
Rectangle itemBounds = myListView->GetItemRect( targetIndex );
if ( targetPoint.X > itemBounds.Left + (itemBounds.Width / 2) )
{
myListView->InsertionMark->AppearsAfterItem = true;
}
else
{
myListView->InsertionMark->AppearsAfterItem = false;
}
}
// Set the location of the insertion mark. If the mouse is
// over the dragged item, the targetIndex value is -1 and
// the insertion mark disappears.
myListView->InsertionMark->Index = targetIndex;
}
// Removes the insertion mark when the mouse leaves the control.
void myListView_DragLeave( Object^ /*sender*/, EventArgs^ /*e*/ )
{
myListView->InsertionMark->Index = -1;
}
// Moves the item to the location of the insertion mark.
void myListView_DragDrop( Object^ /*sender*/, DragEventArgs^ e )
{
// Retrieve the index of the insertion mark;
int targetIndex = myListView->InsertionMark->Index;
// If the insertion mark is not visible, exit the method.
if ( targetIndex == -1 )
{
return;
}
// If the insertion mark is to the right of the item with
// the corresponding index, increment the target index.
if ( myListView->InsertionMark->AppearsAfterItem )
{
targetIndex++;
}
// Retrieve the dragged item.
ListViewItem^ draggedItem = dynamic_cast<ListViewItem^>(e->Data->GetData( ListViewItem::typeid ));
// Insert a copy of the dragged item at the target index.
// A copy must be inserted before the original item is removed
// to preserve item index values.
myListView->Items->Insert( targetIndex, dynamic_cast<ListViewItem^>(draggedItem->Clone()) );
// Remove the original copy of the dragged item.
myListView->Items->Remove( draggedItem );
}
// Sorts ListViewItem objects by index.
ref class ListViewIndexComparer: public System::Collections::IComparer
{
public:
virtual int Compare( Object^ x, Object^ y )
{
return (dynamic_cast<ListViewItem^>(x))->Index - (dynamic_cast<ListViewItem^>(y))->Index;
}
};
};
[STAThread]
int main()
{
Application::EnableVisualStyles();
Application::Run( gcnew ListViewInsertionMarkExample );
}
import System.*;
import System.Drawing.*;
import System.Windows.Forms.*;
public class ListViewInsertionMarkExample extends Form
{
private ListView myListView;
public ListViewInsertionMarkExample()
{
// Initialize myListView.
myListView = new ListView();
myListView.set_Dock(DockStyle.Fill);
myListView.set_View(View.LargeIcon);
myListView.set_MultiSelect(false);
myListView.set_ListViewItemSorter(new ListViewIndexComparer());
// Initialize the insertion mark.
myListView.get_InsertionMark().set_Color(Color.get_Green());
// Add items to myListView.
myListView.get_Items().Add("zero");
myListView.get_Items().Add("one");
myListView.get_Items().Add("two");
myListView.get_Items().Add("three");
myListView.get_Items().Add("four");
myListView.get_Items().Add("five");
// Initialize the drag-and-drop operation when running
// under Windows XP or a later operating system.
if (System.Environment.get_OSVersion().get_Version().get_Major() > 5
|| (System.Environment.get_OSVersion().get_Version().get_Major()
== 5 && System.Environment.get_OSVersion().get_Version().
get_Minor() >= 1)) {
myListView.set_AllowDrop(true);
myListView.add_ItemDrag(new ItemDragEventHandler(
myListView_ItemDrag));
myListView.add_DragEnter(new DragEventHandler(
myListView_DragEnter));
myListView.add_DragOver(new DragEventHandler(myListView_DragOver));
myListView.add_DragLeave(new EventHandler(myListView_DragLeave));
myListView.add_DragDrop(new DragEventHandler(myListView_DragDrop));
}
// Initialize the form.
this.set_Text("ListView Insertion Mark Example");
this.get_Controls().Add(myListView);
} //ListViewInsertionMarkExample
/** @attribute STAThread()
*/
public static void main(String[] args)
{
Application.Run(new ListViewInsertionMarkExample());
} //main
// Starts the drag-and-drop operation when an item is dragged.
private void myListView_ItemDrag(Object sender, ItemDragEventArgs e)
{
myListView.DoDragDrop(e.get_Item(), DragDropEffects.Move);
} //myListView_ItemDrag
// Sets the target drop effect.
private void myListView_DragEnter(Object sender, DragEventArgs e)
{
e.set_Effect(e.get_AllowedEffect());
} //myListView_DragEnter
// Moves the insertion mark as the item is dragged.
private void myListView_DragOver(Object sender, DragEventArgs e)
{
// Retrieve the client coordinates of the mouse pointer.
Point targetPoint = myListView.PointToClient(
new Point(e.get_X(), e.get_Y()));
// Retrieve the index of the item closest to the mouse pointer.
int targetIndex = myListView.get_InsertionMark().
NearestIndex(targetPoint);
// Confirm that the mouse pointer is not over the dragged item.
if (targetIndex > -1) {
// Determine whether the mouse pointer is to the left or
// the right of the midpoint of the closest item and set
// the InsertionMark.AppearsAfterItem property accordingly.
Rectangle itemBounds = myListView.GetItemRect(targetIndex);
if (targetPoint.get_X() > itemBounds.get_Left()
+ itemBounds.get_Width() / 2) {
myListView.get_InsertionMark().set_AppearsAfterItem(true);
}
else {
myListView.get_InsertionMark().set_AppearsAfterItem(false);
}
}
// Set the location of the insertion mark. If the mouse is
// over the dragged item, the targetIndex value is -1 and
// the insertion mark disappears.
myListView.get_InsertionMark().set_Index(targetIndex);
} //myListView_DragOver
// Removes the insertion mark when the mouse leaves the control.
private void myListView_DragLeave(Object sender, EventArgs e)
{
myListView.get_InsertionMark().set_Index(-1);
} //myListView_DragLeave
// Moves the item to the location of the insertion mark.
private void myListView_DragDrop(Object sender, DragEventArgs e)
{
// Retrieve the index of the insertion mark;
int targetIndex = myListView.get_InsertionMark().get_Index();
// If the insertion mark is not visible, exit the method.
if (targetIndex == -1) {
return;
}
// If the insertion mark is to the right of the item with
// the corresponding index, increment the target index.
if (myListView.get_InsertionMark().get_AppearsAfterItem()) {
targetIndex++;
}
// Retrieve the dragged item.
ListViewItem draggedItem = (ListViewItem)(e.get_Data().GetData(
ListViewItem.class.ToType()));
// Insert a copy of the dragged item at the target index.
// A copy must be inserted before the original item is removed
// to preserve item index values.
myListView.get_Items().Insert(targetIndex, (ListViewItem)
draggedItem.Clone());
// Remove the original copy of the dragged item.
myListView.get_Items().Remove(draggedItem);
} //myListView_DragDrop
// Sorts ListViewItem objects by index.
private class ListViewIndexComparer
implements System.Collections.IComparer
{
public int Compare(Object x, Object y)
{
return ((ListViewItem)x).get_Index()
- ((ListViewItem)y).get_Index();
} //Compare
} //ListViewIndexComparer
} //ListViewInsertionMarkExample
Compiling the Code
This example requires:
- References to the System and System.Windows.Forms assemblies.
For information about building this example from the command line for Visual Basic or Visual C#, see Building from the Command Line (Visual Basic) or Command-Line Building. You can also build this example in Visual Studio by pasting the code into a new project. How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio
How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio
How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio
How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio
See Also
Tasks
Walkthrough: Performing a Drag-and-Drop Operation in Windows Forms
Reference
ListView Control Overview (Windows Forms)
ListView
System.Windows.Forms.ListView.InsertionMark
ListViewInsertionMark
Concepts
Windows XP Features and Windows Forms Controls