ListViewInsertionMark Class
Used to indicate the expected drop location when an item is dragged to a new position in a ListView control. This functionality is available only on Windows XP and later.
Assembly: System.Windows.Forms (in System.Windows.Forms.dll)
You can retrieve a ListViewInsertionMark from the InsertionMark property of a ListView control and use it to visually indicate the expected drop location in a drag-and-drop operation when an item is dragged to a new position.
This feature works only when the ListView.AutoArrange property is set to true and when the ListView control does not sort the items automatically. To prevent automatic sorting, the ListView.Sorting property must be set to SortOrder.None and the ListView.View property must be set to View.LargeIcon, View.SmallIcon, or View.Tile. Additionally, the insertion mark feature cannot be used with the ListView grouping feature because the grouping feature orders the items by group membership.
The ListViewInsertionMark class is typically used in a handler for the Control.DragOver or Control.MouseMove event to update the position of the insertion mark as an item is dragged. It is also used in a handler for the Control.DragDrop or Control.MouseUp event to insert a dragged item at the correct location.
To update the position of the insertion mark, follow these steps:
In a handler for the Control.DragOver or Control.MouseMove event, use the ListView.InsertionMark property to access the ListViewInsertionMark object associated with the ListView control.
Use the NearestIndex method to retrieve the index of the item closest to the mouse pointer.
Pass the index value to the ListView.GetItemRect method to retrieve the bounding rectangle of the item.
If the mouse pointer is located to the left of the midpoint of the bounding rectangle, set the AppearsAfterItem property to false; otherwise, set it to true.
Set the Index property to the index value retrieved from the NearestIndex method. The insertion mark appears next to item with the specified index, either to the left or the right, depending on the AppearsAfterItem property value. If an item is dragged over itself, the index is -1 and the insertion mark is hidden.
To insert the dragged item at the correct location, follow these steps:
In a handler for the Control.DragDrop or Control.MouseUp event, use the Index property to determine the current location of the insertion mark. Store this value to be used later as the insertion index.
If the AppearsAfterItem property is set to true, increment the stored insertion index value.
Use the ListView.ListViewItemCollection.Insert method to insert a clone of the dragged item into the ListView.Items collection at the stored insertion index.
Use the ListView.ListViewItemCollection.Remove method to remove the original copy of the dragged item.
You must insert a clone of the dragged item before the original copy is removed so the index values in the ListView.Items collection are not altered before the insertion.
To ensure that the items are displayed in the same order as their index values, you must set the ListView.ListViewItemSorter property to an implementation of the IComparer interface that sorts items by index value. For more information, see the Example section.
You can modify the color of the insertion mark by using the Color property. If you need the size or position of the insertion mark, you can get its bounding rectangle through the Bounds property.
Note: |
|---|
The insertion mark feature is available only on Windows XP and the Windows Server 2003 family when your application calls the Application.EnableVisualStyles method. On earlier operating systems, any code relating to the insertion mark will be ignored and the insertion mark will not appear. As a result, any code that depends on the insertion mark feature may not work correctly. You may want to include a test that determines whether the insertion mark feature is available, and provide alternate functionality when it is unavailable. For example, you may want to bypass all code that implements drag-and-drop item repositioning when running on operating systems that do not support insertion marks. The insertion mark feature is provided by the same library that provides the operating system themes feature. To check for the availability of this library, call the FeatureSupport.IsPresent(Object) method overload and pass in the OSFeature.Themes value. |
The following code example demonstrates how to use the ListView insertion mark feature and implements drag-and-drop item reordering using the standard drag events. The position of the insertion mark is updated in a handler for the Control.DragOver event. In this handler, the position of the mouse pointer is compared to the midpoint of the nearest item, and the result is used to determine whether the insertion mark appears to the left or the right of the item.
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
Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98
The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Note: