ListViewInsertionMark Classe

Definição

Usado para indicar a localização esperada de drop quando um item é arrastado para uma nova posição num ListView controlo. Esta funcionalidade está disponível apenas no Windows XP e versões posteriores.

public ref class ListViewInsertionMark sealed
public sealed class ListViewInsertionMark
type ListViewInsertionMark = class
Public NotInheritable Class ListViewInsertionMark
Herança
ListViewInsertionMark

Exemplos

O exemplo de código seguinte demonstra como usar a ListView funcionalidade de marcação de inserção e implementa a reordenação de itens por arrastar e largar usando os eventos padrão de arrastar. A posição da marca de inserção é atualizada num handler para o Control.DragOver evento. Neste manipulador, a posição do ponteiro do rato é comparada ao ponto médio do item mais próximo, e o resultado é usado para determinar se a marca de inserção aparece à esquerda ou à direita do 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

Observações

Podes recuperar a ListViewInsertionMark da InsertionMark propriedade de um ListView controlo e usá-lo para indicar visualmente a localização esperada de drop numa operação de arrastar e largar quando um item é arrastado para uma nova posição.

Esta funcionalidade funciona apenas quando a ListView.AutoArrange propriedade está definida como true e quando o controlo ListView não ordena automaticamente os itens. Para evitar a ordenação automática, a ListView.Sorting propriedade deve ser definida como SortOrder.None e a ListView.View propriedade deve ser definida para View.LargeIcon, View.SmallIcon, ou View.Tile. Além disso, a funcionalidade de marcação de inserção não pode ser usada com a ListView funcionalidade de agrupamento porque esta ordena os itens por pertença ao grupo.

A ListViewInsertionMark classe é normalmente usada num handler para o Control.DragOver evento ou Control.MouseMove atualizar a posição da marca de inserção à medida que um item é arrastado. Também é usado num handler para o Control.DragDrop evento ou Control.MouseUp inserir um item arrastado no local correto.

Para atualizar a posição da marca de inserção, siga estes passos:

  1. Num handler para o Control.DragOver evento ou, Control.MouseMove use a ListView.InsertionMark propriedade para aceder ao ListViewInsertionMark objeto associado ao ListView controlo.

  2. Use o NearestIndex método para recuperar o índice do item mais próximo do ponteiro do rato.

  3. Passe o valor do índice ao ListView.GetItemRect método para recuperar o retângulo delimitador do item.

  4. Se o ponteiro do rato estiver localizado à esquerda do ponto médio do retângulo delimitador, defina a AppearsAfterItem propriedade para false; caso contrário, defina-a para true.

  5. Defina a Index propriedade para o valor do índice recuperado do NearestIndex método. A marca de inserção aparece ao lado do item com o índice especificado, à esquerda ou à direita, dependendo do valor da AppearsAfterItem propriedade. Se um item for arrastado sobre si próprio, o índice é -1 e a marca de inserção fica oculta.

Para inserir o item arrastado no local correto, siga estes passos:

  1. Num handler para o Control.DragDrop evento ou Control.MouseUp , use a Index propriedade para determinar a localização atual da marca de inserção. Armazene este valor para ser usado mais tarde como índice de inserção.

  2. Se a AppearsAfterItem propriedade estiver definida para true, incremente o valor do índice de inserção armazenado.

  3. Use o ListView.ListViewItemCollection.Insert método para inserir um clone do item arrastado na ListView.Items coleção no índice de inserção armazenado.

  4. Use o ListView.ListViewItemCollection.Remove método para remover a cópia original do item arrastado.

Deve inserir um clone do item arrastado antes de a cópia original ser removida, para que os valores do índice na ListView.Items coleção não sejam alterados antes da inserção.

Para garantir que os itens são exibidos na mesma ordem que os seus valores de índice, deve definir a ListView.ListViewItemSorter propriedade para uma implementação da IComparer interface que ordena os itens por valor de índice. Para mais informações, consulte a secção de Exemplos.

Pode modificar a cor da marca de inserção usando a Color propriedade. Se precisares do tamanho ou da posição da marca de inserção, podes obter o seu retângulo delimitador através da Bounds propriedade.

Note

A funcionalidade de marca de inserção está disponível apenas no Windows XP e na família Windows Server 2003 quando a sua aplicação chama o método Application.EnableVisualStyles. Nos sistemas operativos anteriores, qualquer código relacionado com a marca de inserção será ignorado e a marca de inserção não aparecerá. Como resultado, qualquer código que dependa da funcionalidade de marca de inserção pode não funcionar corretamente. Pode querer incluir um teste que determine se a funcionalidade de marca de inserção está disponível e fornecer funcionalidades alternativas quando esta não estiver disponível. Por exemplo, pode querer contornar todo o código que implemente reposicionamento de itens por arrastar e largar ao correr em sistemas operativos que não suportam marcas de inserção.

A funcionalidade de marca de inserção é fornecida pela mesma biblioteca que fornece a funcionalidade de temas do sistema operativo. Para verificar a disponibilidade desta biblioteca, chama o FeatureSupport.IsPresent(Object) método overload e passa o OSFeature.Themes valor.

Propriedades

Name Description
AppearsAfterItem

Recebe ou define um valor que indica se a marca de inserção aparece à direita do item com o índice especificado pela Index propriedade.

Bounds

Obtém o retângulo delimitador da marca de inserção.

Color

Obtém ou define a cor da marca de inserção.

Index

Obtém ou define o índice do item ao lado do qual aparece a marca de inserção.

Métodos

Name Description
Equals(Object)

Determina se o objeto especificado é igual ao objeto atual.

(Herdado de Object)
GetHashCode()

Serve como função de hash predefinida.

(Herdado de Object)
GetType()

Obtém o Type da instância atual.

(Herdado de Object)
MemberwiseClone()

Cria uma cópia superficial do atual Object.

(Herdado de Object)
NearestIndex(Point)

Recupera o índice do item mais próximo do ponto especificado.

ToString()

Devolve uma cadeia que representa o objeto atual.

(Herdado de Object)

Aplica-se a

Ver também