Поделиться через


Практическое руководство. Индикация места вставки в элементе управления ListView в Windows Forms

Обновлен: Ноябрь 2007

Метка вставки элемента управления ListView показывает пользователю, куда будут помещены перетаскиваемые элементы. Когда пользователь перетаскивает элемент на точку между двумя другими элементами, метка вставки показывает ожидаемое новое расположение элемента.

hx62xfd2.alert_note(ru-ru,VS.90).gifПримечание.

Метка вставки доступна только в Windows XP Home Edition, Windows XP Professional, Windows Server 2003 при вызове приложением метода Application.EnableVisualStyles. В предыдущих версиях операционных систем код, связанный с меткой вставки, не действует, и метка вставки отображаться не будут. Дополнительные сведения см. в разделе ListViewInsertionMark.

На следующем рисунке показана метка вставки.

Маркер вставки ListView

В следующем примере кода демонстрируется использование этой функции.

Пример

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 

Компиляция кода

Для этого примера требуются следующие компоненты.

  • Ссылки на сборки System и System.Windows.Forms.

Дополнительные сведения о построении этого примера из командной строки в среде Visual Basic или Visual C# см. в разделе Построение из командной строки (Visual Basic) или Построение из командной строки с помощью csc.exe. Можно также построить этот пример в Visual Studio путем вставки кода в новый проект. Дополнительные сведения см. в разделах Практическое руководство. Компиляция и выполнение откомпилированного примера кода формы Windows Forms с помощью Visual Studio и Практическое руководство. Компиляция и выполнение откомпилированного примера кода формы Windows Forms с помощью Visual Studio и Практическое руководство. Компиляция и выполнение откомпилированного примера кода формы Windows Forms с помощью Visual Studio.

См. также

Задачи

Пример. Выполнение операции перетаскивания в Windows Forms

Основные понятия

Возможности Windows XP и элементы управления Windows Forms

Ссылки

Общие сведения об элементе управления ListView (Windows Forms)

ListView

ListView.InsertionMark

ListViewInsertionMark

Другие ресурсы

Элемент управления ListView (Windows Forms)