ListViewInsertionMark ListViewInsertionMark ListViewInsertionMark ListViewInsertionMark Class

定义

ListView 控件中将某项拖动到新位置时,用于指示期望的拖放位置。Used to indicate the expected drop location when an item is dragged to a new position in a ListView control. 此功能仅适用于 Windows XP 和更高版本。This functionality is available only on Windows XP and later.

public ref class ListViewInsertionMark sealed
public sealed class ListViewInsertionMark
type ListViewInsertionMark = class
Public NotInheritable Class ListViewInsertionMark
继承
ListViewInsertionMarkListViewInsertionMarkListViewInsertionMarkListViewInsertionMark

示例

下面的代码示例演示如何使用ListView插入标记功能并实现使用标准拖动事件的拖放项重新排序。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. Control.DragOver事件的处理程序中更新插入标记的位置。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.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 );
}
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;
        }
    }

}
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

    <STAThread()> _
    Shared Sub Main()
        Application.EnableVisualStyles()
        Application.Run(New ListViewInsertionMarkExample())
    End Sub
    
    ' 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
    
    ' Sets the target drop effect.
    Private Sub myListView_DragEnter(sender As Object, e As DragEventArgs)
        e.Effect = e.AllowedEffect
    End Sub
    
    ' 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

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

End Class

注解

可以ListViewInsertionMark ListView从控件的属性中检索, 并在将项拖动到新位置时, 使用它直观地指示拖放操作中的预期放置位置。 InsertionMarkYou 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.

此功能仅在以下情况ListView.AutoArrange下有效: 当true属性设置为ListView时, 如果控件未自动对项进行排序, 则为。This feature works only when the ListView.AutoArrange property is set to true and when the ListView control does not sort the items automatically. 若要防止自动排序, ListView.Sorting属性必须设置为SortOrder.None , 并且ListView.View属性必须设置为View.LargeIconView.SmallIconView.TileTo 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. 此外, 插入标记功能不能用于ListView分组功能, 因为分组功能按组成员按顺序对项进行排序。Additionally, the insertion mark feature cannot be used with the ListView grouping feature because the grouping feature orders the items by group membership.

类通常用于Control.DragOverControl.MouseMove事件的处理程序中, 用于在拖动项时更新插入标记的位置。 ListViewInsertionMarkThe 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. 它还在Control.DragDropControl.MouseUp事件的处理程序中用于将拖动的项插入到正确的位置。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. Control.DragOver ListViewInsertionMarkControl.MouseMove事件的处理程序中, 使用ListView.InsertionMark属性访问与该ListView控件关联的对象。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. NearestIndex使用方法检索离鼠标指针最近的项的索引。Use the NearestIndex method to retrieve the index of the item closest to the mouse pointer.

  3. 将索引值传递给ListView.GetItemRect方法以检索项的边框。Pass the index value to the ListView.GetItemRect method to retrieve the bounding rectangle of the item.

  4. 如果鼠标指针位于边界矩形中点的左侧, 则将AppearsAfterItem属性设置为false; 否则, 请将其设置为trueIf 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. 将属性设置为从方法检索到的索引值。 NearestIndex IndexSet the Index property to the index value retrieved from the NearestIndex method. 插入标记将显示在具有指定索引的项的旁边, 具体取决AppearsAfterItem于属性值。The insertion mark appears next to item with the specified index, either to the left or the right, depending on the AppearsAfterItem property value. 如果将某个项拖动到其自身上, 则索引为-1, 并且插入标记处于隐藏状态。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. Control.DragDrop IndexControl.MouseUp事件的处理程序中, 使用属性来确定插入标记的当前位置。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. true如果将AppearsAfterItem属性设置为, 则递增存储的插入索引值。If the AppearsAfterItem property is set to true, increment the stored insertion index value.

  3. 使用方法将拖动的项的克隆插入ListView.Items到集合中存储的插入索引处。 ListView.ListViewItemCollection.InsertUse the ListView.ListViewItemCollection.Insert method to insert a clone of the dragged item into the ListView.Items collection at the stored insertion index.

  4. ListView.ListViewItemCollection.Remove使用方法可删除拖动项的原始副本。Use the ListView.ListViewItemCollection.Remove method to remove the original copy of the dragged item.

在删除原始副本之前, 必须先插入拖动项的复本, 以便在插入之前不更改ListView.Items集合中的索引值。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.

若要确保项的显示顺序与其索引值相同, 必须将ListView.ListViewItemSorter属性设置为按索引值对项进行排序的IComparer接口的实现。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.

您可以使用Color属性修改插入标记的颜色。You can modify the color of the insertion mark by using the Color property. 如果需要插入标记的大小或位置, 可以通过Bounds属性获取其边框。If you need the size or position of the insertion mark, you can get its bounding rectangle through the Bounds property.

备注

当应用程序调用Application.EnableVisualStyles方法时, 插入标记功能仅在 windows XP 和 windows Server 2003 家族上可用。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. 若要检查此库的可用性, 请调用FeatureSupport.IsPresent(Object)方法重载, 并传入OSFeature.Themes值。To check for the availability of this library, call the FeatureSupport.IsPresent(Object) method overload and pass in the OSFeature.Themes value.

属性

AppearsAfterItem AppearsAfterItem AppearsAfterItem AppearsAfterItem

获取或设置一个值,该值指示是否在项的右侧显示插入标记,该项带有 Index 属性指定的索引。Gets or sets a value indicating whether the insertion mark appears to the right of the item with the index specified by the Index property.

Bounds Bounds Bounds Bounds

获取插入标记的边框。Gets the bounding rectangle of the insertion mark.

Color Color Color Color

获取或设置此插入标记的颜色。Gets or sets the color of the insertion mark.

Index Index Index Index

获取或设置与插入标记旁边的项的索引。Gets or sets the index of the item next to which the insertion mark appears.

方法

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

确定指定的对象是否等于当前对象。Determines whether the specified object is equal to the current object.

(Inherited from Object)
GetHashCode() GetHashCode() GetHashCode() GetHashCode()

作为默认哈希函数。Serves as the default hash function.

(Inherited from Object)
GetType() GetType() GetType() GetType()

获取当前实例的 TypeGets the Type of the current instance.

(Inherited from Object)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(Inherited from Object)
NearestIndex(Point) NearestIndex(Point) NearestIndex(Point) NearestIndex(Point)

检索距离指定点最近的项的索引。Retrieves the index of the item closest to the specified point.

ToString() ToString() ToString() ToString()

返回表示当前对象的字符串。Returns a string that represents the current object.

(Inherited from Object)

适用于

另请参阅