En el siguiente ejemplo se muestra una operación de arrastrar y colocar entre dos controles ListBox. En el ejemplo se llama al método DoDragDrop cuando se inicia la acción de arrastrar. La acción de arrastrar se inicia si se ha movido el mouse más de SystemInformation.DragSize desde su ubicación durante el evento MouseDown. El método IndexFromPoint se utiliza para determinar el índice del elemento que se va a arrastrar durante el evento MouseDown.
En el ejemplo también se muestra la forma de utilizar cursores personalizados para la operación de arrastrar y colocar. En este ejemplo, se supone que hay dos archivos de cursor (3dwarro.cur y 3dwno.cur) en el directorio de la aplicación para los cursores de arrastrar y colocar personalizados, respectivamente. Los cursores personalizados se utilizan si se ha activado UseCustomCursorsCheckCheckBox. Los cursores personalizados se establecen en el controlador de eventos GiveFeedback.
El estado del teclado se evalúa en el controlador de eventos DragOver en el ListBox de la derecha para determinar la operación de arrastrar en función del estado de las teclas MAYÚS, CTRL, ALT o CTRL+ALT. La ubicación de ListBox donde se produciría la operación de colocar también se determina durante el evento DragOver. Si los datos que se van a colocar no son de tipo String, DragEventArgs.Effect se establece en DragDropEffects.None. Por último, el estado de la operación de colocar se muestra en DropLocationLabelLabel.
Los datos que se van a colocar en el ListBox de la derecha se determinan en el controlador de eventos DragDrop y el valor String se agrega a la ubicación apropiada de ListBox. Si la operación de arrastrar se realiza fuera de los límites del formulario, la operación de arrastrar y colocar se cancelará en el controlador de eventos QueryContinueDrag.
En este fragmento de código se muestra cómo utilizar la enumeración DragDropEffects. Para obtener el ejemplo completo del código, vea el método DoDragDrop.
Private Sub ListDragTarget_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) Handles ListDragTarget.DragOver
' Determine whether string data exists in the drop data. If not, then
' the drop effect reflects that the drop cannot occur.
If Not (e.Data.GetDataPresent(GetType(System.String))) Then
e.Effect = DragDropEffects.None
DropLocationLabel.Text = "None - no string data."
Return
End If
' Set the effect based upon the KeyState.
If ((e.KeyState And (8 + 32)) = (8 + 32) And _
(e.AllowedEffect And DragDropEffects.Link) = DragDropEffects.Link) Then
' KeyState 8 + 32 = CTL + ALT
' Link drag-and-drop effect.
e.Effect = DragDropEffects.Link
ElseIf ((e.KeyState And 32) = 32 And _
(e.AllowedEffect And DragDropEffects.Link) = DragDropEffects.Link) Then
' ALT KeyState for link.
e.Effect = DragDropEffects.Link
ElseIf ((e.KeyState And 4) = 4 And _
(e.AllowedEffect And DragDropEffects.Move) = DragDropEffects.Move) Then
' SHIFT KeyState for move.
e.Effect = DragDropEffects.Move
ElseIf ((e.KeyState And 8) = 8 And _
(e.AllowedEffect And DragDropEffects.Copy) = DragDropEffects.Copy) Then
' CTL KeyState for copy.
e.Effect = DragDropEffects.Copy
ElseIf ((e.AllowedEffect And DragDropEffects.Move) = DragDropEffects.Move) Then
' By default, the drop action should be move, if allowed.
e.Effect = DragDropEffects.Move
Else
e.Effect = DragDropEffects.None
End If
' Gets the index of the item the mouse is below.
' The mouse locations are relative to the screen, so they must be
' converted to client coordinates.
indexOfItemUnderMouseToDrop = _
ListDragTarget.IndexFromPoint(ListDragTarget.PointToClient(New Point(e.X, e.Y)))
' Updates the label text.
If (indexOfItemUnderMouseToDrop <> ListBox.NoMatches) Then
DropLocationLabel.Text = "Drops before item #" & (indexOfItemUnderMouseToDrop + 1)
Else
DropLocationLabel.Text = "Drops at the end."
End If
End Sub
private void ListDragTarget_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
{
// Determine whether string data exists in the drop data. If not, then
// the drop effect reflects that the drop cannot occur.
if (!e.Data.GetDataPresent(typeof(System.String))) {
e.Effect = DragDropEffects.None;
DropLocationLabel.Text = "None - no string data.";
return;
}
// Set the effect based upon the KeyState.
if ((e.KeyState & (8+32)) == (8+32) &&
(e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) {
// KeyState 8 + 32 = CTL + ALT
// Link drag-and-drop effect.
e.Effect = DragDropEffects.Link;
} else if ((e.KeyState & 32) == 32 &&
(e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) {
// ALT KeyState for link.
e.Effect = DragDropEffects.Link;
} else if ((e.KeyState & 4) == 4 &&
(e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) {
// SHIFT KeyState for move.
e.Effect = DragDropEffects.Move;
} else if ((e.KeyState & 8) == 8 &&
(e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy) {
// CTL KeyState for copy.
e.Effect = DragDropEffects.Copy;
} else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) {
// By default, the drop action should be move, if allowed.
e.Effect = DragDropEffects.Move;
} else
e.Effect = DragDropEffects.None;
// Get the index of the item the mouse is below.
// The mouse locations are relative to the screen, so they must be
// converted to client coordinates.
indexOfItemUnderMouseToDrop =
ListDragTarget.IndexFromPoint(ListDragTarget.PointToClient(new Point(e.X, e.Y)));
// Updates the label text.
if (indexOfItemUnderMouseToDrop != ListBox.NoMatches){
DropLocationLabel.Text = "Drops before item #" + (indexOfItemUnderMouseToDrop + 1);
} else
DropLocationLabel.Text = "Drops at the end.";
}
void ListDragTarget_DragOver( Object^ /*sender*/, System::Windows::Forms::DragEventArgs^ e )
{
// Determine whether string data exists in the drop data. If not, then
// the drop effect reflects that the drop cannot occur.
if ( !e->Data->GetDataPresent( System::String::typeid ) )
{
e->Effect = DragDropEffects::None;
DropLocationLabel->Text = "None - no string data.";
return;
}
// Set the effect based upon the KeyState.
if ( (e->KeyState & (8 + 32)) == (8 + 32) && ((e->AllowedEffect & DragDropEffects::Link) == DragDropEffects::Link) )
{
// KeyState 8 + 32 = CTL + ALT
// Link drag-and-drop effect.
e->Effect = DragDropEffects::Link;
}
else
if ( (e->KeyState & 32) == 32 && ((e->AllowedEffect & DragDropEffects::Link) == DragDropEffects::Link) )
{
// ALT KeyState for link.
e->Effect = DragDropEffects::Link;
}
else
if ( (e->KeyState & 4) == 4 && ((e->AllowedEffect & DragDropEffects::Move) == DragDropEffects::Move) )
{
// SHIFT KeyState for move.
e->Effect = DragDropEffects::Move;
}
else
if ( (e->KeyState & 8) == 8 && ((e->AllowedEffect & DragDropEffects::Copy) == DragDropEffects::Copy) )
{
// CTL KeyState for copy.
e->Effect = DragDropEffects::Copy;
}
else
if ( (e->AllowedEffect & DragDropEffects::Move) == DragDropEffects::Move )
{
// By default, the drop action should be move, if allowed.
e->Effect = DragDropEffects::Move;
}
else
e->Effect = DragDropEffects::None;
// Get the index of the item the mouse is below.
// The mouse locations are relative to the screen, so they must be
// converted to client coordinates.
indexOfItemUnderMouseToDrop = ListDragTarget->IndexFromPoint( ListDragTarget->PointToClient( Point(e->X,e->Y) ) );
// Updates the label text.
if ( indexOfItemUnderMouseToDrop != ListBox::NoMatches )
{
DropLocationLabel->Text = String::Concat( "Drops before item # ", (indexOfItemUnderMouseToDrop + 1) );
}
else
DropLocationLabel->Text = "Drops at the end.";
}
private void listDragTarget_DragOver(Object sender,
System.Windows.Forms.DragEventArgs e)
{
// Determine whether string data exists in the drop data. If not, then
// the drop effect reflects that the drop cannot occur.
if (!(e.get_Data().GetDataPresent(String.class.ToType()))) {
e.set_Effect(DragDropEffects.None);
dropLocationLabel.set_Text("None - no string data.");
return;
}
// Set the effect based upon the KeyState.
if ((e.get_KeyState() & 8 + 32) == 8 + 32 && (e.get_AllowedEffect()
& DragDropEffects.Link) == DragDropEffects.Link) {
// KeyState 8 + 32 = CTL + ALT
// Link drag-and-drop effect.
e.set_Effect(DragDropEffects.Link);
}
else {
if ((e.get_KeyState() & 32) == 32 && (e.get_AllowedEffect()
& DragDropEffects.Link) == DragDropEffects.Link) {
// ALT KeyState for link.
e.set_Effect(DragDropEffects.Link);
}
else {
if ((e.get_KeyState() & 4) == 4 && (e.get_AllowedEffect()
& DragDropEffects.Move) == DragDropEffects.Move) {
// SHIFT KeyState for move.
e.set_Effect(DragDropEffects.Move);
}
else {
if ((e.get_KeyState() & 8) == 8 && (e.get_AllowedEffect()
& DragDropEffects.Copy) == DragDropEffects.Copy) {
// CTL KeyState for copy.
e.set_Effect(DragDropEffects.Copy);
}
else {
if ((e.get_AllowedEffect() & DragDropEffects.Move)
== DragDropEffects.Move) {
// By default, the drop action should be move,
//if allowed.
e.set_Effect(DragDropEffects.Move);
}
else {
e.set_Effect(DragDropEffects.None);
}
} // Get the index of the item the mouse is below.
}
} // The mouse locations are relative to the screen, so they
// must be converted to client coordinates.
}
indexOfItemUnderMouseToDrop = listDragTarget.IndexFromPoint(
listDragTarget.PointToClient(new Point(e.get_X(), e.get_Y())));
// Updates the label text.
if (indexOfItemUnderMouseToDrop != ListBox.NoMatches) {
dropLocationLabel.set_Text("Drops before item #"
+ (indexOfItemUnderMouseToDrop + 1));
}
else {
dropLocationLabel.set_Text("Drops at the end.");
}
} //listDragTarget_DragOver