Export (0) Print
Expand All

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.

System.Object
  System.Windows.Forms.ListViewInsertionMark

Namespace:  System.Windows.Forms
Assembly:  System.Windows.Forms (in System.Windows.Forms.dll)

public sealed class ListViewInsertionMark

The ListViewInsertionMark type exposes the following members.

  NameDescription
Public propertyAppearsAfterItemGets or sets a value indicating whether the insertion mark appears to the right of the item with the index specified by the Index property.
Public propertyBoundsGets the bounding rectangle of the insertion mark.
Public propertyColorGets or sets the color of the insertion mark.
Public propertyIndexGets or sets the index of the item next to which the insertion mark appears.
Top

  NameDescription
Public methodEquals(Object)Determines whether the specified object is equal to the current object. (Inherited from Object.)
Public methodGetHashCodeServes as the default hash function. (Inherited from Object.)
Public methodGetTypeGets the Type of the current instance. (Inherited from Object.)
Public methodNearestIndexRetrieves the index of the item closest to the specified point.
Public methodToStringReturns a string that represents the current object. (Inherited from Object.)
Top

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:

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

  2. Use the NearestIndex method to retrieve the index of the item closest to the mouse pointer.

  3. Pass the index value to the ListView.GetItemRect method to retrieve the bounding rectangle of the item.

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

  5. 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:

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

  2. If the AppearsAfterItem property is set to true, increment the stored insertion index value.

  3. Use the ListView.ListViewItemCollection.Insert method to insert a clone of the dragged item into the ListView.Items collection at the stored insertion index.

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

NoteNote

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.

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

}

.NET Framework

Supported in: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
Show:
© 2014 Microsoft