Información general sobre la función de arrastrar y colocar
En este tema se proporciona información general sobre la compatibilidad con arrastrar y colocar en aplicaciones de Windows Presentation Foundation (WPF). Arrastrar y colocar se refiere normalmente a un método de transferencia de datos que implica el uso de un mouse (o cualquier otro dispositivo señalador) para seleccionar uno o más objetos, arrastrar estos objetos sobre un destino deseado en la interfaz de usuario (UI) y soltarlos.
Compatibilidad con arrastrar y colocar en WPF
Las operaciones de arrastrar y colocar suelen incluir dos partes: un origen de arrastre en el que se origina el objeto arrastrado y un destino de colocación que recibe el objeto colocado. El origen de arrastre y el destino de colocación pueden ser elementos de la interfaz de usuario de la misma aplicación o de otra aplicación.
El tipo y número de objetos que se pueden manipular con arrastrar y colocar es completamente arbitrario. Por ejemplo, los archivos, las carpetas y las selecciones de contenido son algunos de los objetos más comunes que se manipulan mediante operaciones de arrastrar y colocar.
Las acciones concretas realizadas durante una operación de arrastrar y colocar son específicas de la aplicación y a menudo están determinadas por el contexto. Por ejemplo, si se arrastra una selección de archivos de una carpeta a otra en el mismo dispositivo de almacenamiento los archivos se mueven de forma predeterminada, mientras que si se arrastran archivos de un recurso compartido de la Convención de nomenclatura universal (UNC) a una carpeta local, los archivos se copian de forma predeterminada.
Las funciones de arrastrar y colocar proporcionadas por WPF están diseñadas para ser altamente flexibles y personalizables, para que admitan una amplia variedad de escenarios de arrastrar y colocar. Arrastrar y colocar permite manipular objetos en una sola aplicación o entre aplicaciones diferentes. La operación de arrastrar y colocar entre aplicaciones de WPF y otras aplicaciones de Windows también es totalmente compatible.
En WPF, cualquier UIElement o ContentElement puede participar en una operación de arrastrar y colocar. Los eventos y los métodos necesarios para las operaciones de arrastrar y colocar están definidos en la clase DragDrop. Las clases UIElement y ContentElement contienen un alias para los eventos adjuntos DragDrop, de modo que los eventos aparezcan en la lista de miembros de clase cuando se hereda un UIElement o ContentElement como elemento base. Los controladores de eventos que están asociados a estos eventos se asocian al evento adjunto DragDrop subyacente y reciben la misma instancia de datos de evento. Para obtener más información, vea el evento UIElement.Drop.
Importante
La operación de arrastrar y colocar de OLE no funciona en la zona de Internet.
Transferencia de datos
Arrastrar y colocar es parte de un área más general de transferencia de datos. La transferencia de datos incluye la operación de arrastrar y colocar, así como la operación de copiar y pegar. Una operación de arrastrar y colocar es análoga a una operación de copiar y pegar o cortar y pegar que se usa para transferir datos de un objeto o aplicación a otro mediante el Portapapeles del sistema. Ambos tipos de operaciones requieren:
Un objeto de origen que proporciona los datos.
Una manera de almacenar temporalmente los datos transferidos.
Un objeto de destino que recibe los datos.
En una operación de copiar y pegar, el Portapapeles del sistema se usa para almacenar temporalmente los datos transferidos; en una operación de arrastrar y colocar, se usa un DataObject para almacenar los datos. Desde el punto de vista conceptual, un objeto de datos consta de uno o más pares de Object que contienen los datos reales y un identificador de formato de datos correspondiente.
El origen de arrastre inicia una operación de arrastrar y colocar llamando al método estático DragDrop.DoDragDrop y transfiriéndole los datos transferidos. El método DoDragDrop ajustará automáticamente los datos en un DataObject, si es necesario. Para un mayor control del formato de datos, puede ajustar los datos en un DataObject antes de pasarlos al método DoDragDrop. El destino de colocación es responsable de extraer los datos del DataObject. Para obtener más información sobre cómo trabajar con objetos de datos, consulte Datos y objetos de datos.
El origen y el destino de una operación de arrastrar y colocar son elementos de la interfaz de usuario; sin embargo, los datos que se transfieren no suelen tener una representación visual. Puede escribir código para proporcionar una representación visual de los datos que se arrastran, como ocurre al arrastrar archivos en el Explorador de Windows. De forma predeterminada, se proporciona información al usuario cambiando el cursor para representar el efecto que la operación de arrastrar y colocar tendrá en los datos, por ejemplo si los datos se mueven o se copian.
Efectos de arrastrar y colocar
Las operaciones de arrastrar y colocar pueden tener efectos distintos en los datos transferidos. Por ejemplo, puede copiar los datos o puede mover los datos. WPF define una enumeración DragDropEffects que puede usar para especificar el efecto de una operación de arrastrar y colocar. En el origen de arrastre, puede especificar los efectos que el origen permitirá en el método DoDragDrop. En el destino de colocación, puede especificar el efecto que pretende tener el destino en la propiedad Effects de la clase DragEventArgs. Cuando el destino de colocación especifica su efecto deseado en el evento DragOver, esta información se devuelve al origen de arrastre en el evento GiveFeedback. El origen de arrastre usa esta información para informar al usuario de qué efecto pretende tener en los datos el destino de colocación. Cuando se colocan los datos, el destino de colocación especifica su efecto real en el evento Drop. Esta información se devuelve al origen de arrastre como valor devuelto del método DoDragDrop. Si el destino de colocación devuelve un efecto que no está en la lista de orígenes de arrastre de allowedEffects
, la operación de arrastrar y colocar se cancela sin que se produzca ninguna transferencia de datos.
Es importante recordar que, en WPF, los valores DragDropEffects solo se usan para proporcionar comunicación entre el origen de arrastre y el destino de colocación relativa a los efectos de la operación de arrastrar y colocar. El efecto real de la operación de arrastrar y colocar depende de que se escriba el código adecuado en la aplicación.
Por ejemplo, el destino de colocación podría especificar que el efecto de colocar datos es mover los datos. Sin embargo, para mover los datos, estos deben agregarse al elemento de destino y quitarse del elemento de origen. El elemento de origen podría indicar que permite mover los datos, pero si no se proporciona el código para quitar los datos del elemento de origen, el resultado final será que los datos se copian pero no se mueven.
Eventos de arrastrar y colocar
Las operaciones de arrastrar y colocar admiten un modelo basado en eventos. El origen de arrastre y el destino de colocación usan un conjunto estándar de eventos para controlar las operaciones de arrastrar y colocar. Las tablas siguientes resumen los eventos estándar de arrastrar y colocar. Se trata de eventos adjuntos a la clase DragDrop. Para obtener más información sobre los eventos adjuntos, consulte Información general sobre eventos adjuntos.
Eventos del origen de arrastre
Evento | Resumen |
---|---|
GiveFeedback | Este evento se produce continuamente durante una operación de arrastrar y colocar y permite al origen de colocación proporcionar información al usuario. Esta información suelen proporcionarse mediante un cambio en la apariencia del puntero del mouse para indicar los efectos permitidos por el destino de colocación. Se trata de un evento de propagación. |
QueryContinueDrag | Este evento se produce cuando hay un cambio en los estados del botón del mouse o el teclado durante una operación de arrastrar y colocar, y permite al origen de colocación cancelar la operación de arrastrar y colocar en función de los estados del botón o del teclado. Se trata de un evento de propagación. |
PreviewGiveFeedback | Versión de tunelización de GiveFeedback. |
PreviewQueryContinueDrag | Versión de tunelización de QueryContinueDrag. |
Eventos del destino de colocación
Evento | Resumen |
---|---|
DragEnter | Este evento se produce cuando se arrastra un objeto dentro de los límites del destino de colocación. Se trata de un evento de propagación. |
DragLeave | Este evento se produce cuando se arrastra un objeto fuera de los límites del destino de colocación. Se trata de un evento de propagación. |
DragOver | Este evento se produce continuamente mientras se arrastra (se mueve) un objeto dentro de los límites del destino de colocación. Se trata de un evento de propagación. |
Drop | Este evento se produce cuando se coloca un objeto en el destino de colocación. Se trata de un evento de propagación. |
PreviewDragEnter | Versión de tunelización de DragEnter. |
PreviewDragLeave | Versión de tunelización de DragLeave. |
PreviewDragOver | Versión de tunelización de DragOver. |
PreviewDrop | Versión de tunelización de Drop. |
Para controlar los eventos de arrastrar y colocar para las instancias de un objeto, agregue controladores para los eventos enumerados en las tablas anteriores. Para controlar los eventos de arrastrar y colocar en el nivel de clase, invalide los métodos virtuales On*Event y On*PreviewEvent correspondientes. Para obtener más información, consulte Control de clases de eventos enrutados mediante clases base de control.
Implementación de arrastrar y colocar
Un elemento de la interfaz de usuario puede ser un origen de arrastre, un destino de colocación o ambos. Para implementar la operación básica de arrastrar y colocar, escriba código para iniciar la operación de arrastrar y colocar y para procesar los datos colocados. Puede mejorar la experiencia de arrastrar y colocar controlando los eventos de arrastrar y colocar opcionales.
Para implementar la operación básica de arrastrar y colocar, realice las siguientes tareas:
Identifique el elemento que será un origen de arrastre. Un origen de arrastre puede ser un UIElement o un ContentElement.
Cree un controlador de eventos en el origen de arrastre que iniciará la operación de arrastrar y colocar. El evento suele ser un evento MouseMove.
En el controlador de eventos del origen de arrastre, llame al método DoDragDrop para que inicie la operación de arrastrar y colocar. En la llamada a DoDragDrop, especifique el origen de arrastre, los datos que se van a transferir y los efectos permitidos.
Identifique el elemento que será un destino de colocación. Un destino de colocación puede ser un UIElement o un ContentElement.
En el destino de colocación, establezca la propiedad AllowDrop en
true
.En el destino de colocación, cree un controlador de eventos Drop para procesar los datos colocados.
En el controlador de eventos Drop, extraiga los datos de DragEventArgs mediante los métodos GetDataPresent y GetData.
En el controlador de eventos Drop, use los datos para realizar la operación de arrastrar y colocar deseada.
Puede mejorar la implementación de arrastrar y colocar creando un DataObject personalizado y controlando eventos opcionales de origen de arrastre y destino de colocación, como se muestra en las siguientes tareas:
Para transferir datos personalizados o varios elementos de datos, cree un DataObject para pasar al método DoDragDrop.
Para realizar acciones adicionales durante un arrastre, controle los eventos DragEnter, DragOver y DragLeave en el destino de colocación.
Para cambiar la apariencia del puntero del mouse, controle el evento GiveFeedback en el origen de arrastre.
Para cambiar cómo se cancela la operación de arrastrar y colocar, controle el evento QueryContinueDrag en el origen de arrastre.
Ejemplo de arrastrar y colocar
En esta sección se describe cómo se implementa una operación de arrastrar y colocar para un elemento Ellipse. Ellipse es tanto un origen de arrastre como un destino de colocación. Los datos transferidos son la representación de cadena de la propiedad Fill de la elipse. El siguiente XAML muestra el elemento Ellipse y los eventos relacionados de arrastrar y colocar que controla. Si desea conocer los pasos completos para implementar una función de arrastrar y colocar, consulte Tutorial: Habilitar la técnica de arrastrar y colocar en un control de usuario.
<Ellipse Height="50" Width="50" Fill="Green"
MouseMove="ellipse_MouseMove"
GiveFeedback="ellipse_GiveFeedback"
AllowDrop="True"
DragEnter="ellipse_DragEnter" DragLeave="ellipse_DragLeave"
DragOver="ellipse_DragOver" Drop="ellipse_Drop" />
Habilitar un elemento para que sea un origen de arrastre
Un objeto que es un origen de arrastre es responsable de:
Identificar cuándo se produce un arrastre.
Iniciar la operación de arrastrar y colocar.
Identificar los datos que se van a transferir.
Especificar los efectos que puede tener la operación de arrastrar y colocar en los datos transferidos.
El origen de arrastre también puede proporcionar información al usuario sobre las acciones permitidas (mover, copiar, ninguna) y puede cancelar la operación de arrastrar y colocar en función de las acciones del usuario, como presionar la tecla ESC durante la operación de arrastre.
Es responsabilidad de la aplicación determinar cuándo se produce un arrastre y, a continuación, iniciar la operación de arrastrar y colocar mediante una llamada al método DoDragDrop. Normalmente, es cuando se produce un evento MouseMove en el elemento que se va a arrastrar mientras se presiona un botón del mouse. En el ejemplo siguiente se muestra cómo iniciar una operación de arrastrar y colocar desde el controlador de eventos MouseMove de un elemento Ellipse para convertirlo en un origen de arrastre. Los datos transferidos son la representación de cadena de la propiedad Fill de la elipse.
private void ellipse_MouseMove(object sender, MouseEventArgs e)
{
Ellipse ellipse = sender as Ellipse;
if (ellipse != null && e.LeftButton == MouseButtonState.Pressed)
{
DragDrop.DoDragDrop( ellipse,
ellipse.Fill.ToString(),
DragDropEffects.Copy);
}
}
Private Sub Ellipse_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseEventArgs)
Dim ellipse = TryCast(sender, Ellipse)
If ellipse IsNot Nothing AndAlso e.LeftButton = MouseButtonState.Pressed Then
DragDrop.DoDragDrop(ellipse, ellipse.Fill.ToString(), DragDropEffects.Copy)
End If
End Sub
Dentro del controlador de eventos MouseMove, llame al método DoDragDrop para que inicie la operación de arrastrar y colocar. El método DoDragDrop toma tres parámetros:
dragSource
– Una referencia al objeto de dependencia que es el origen de los datos transferidos; suele ser el origen del evento MouseMove.data
– Un objeto que contiene los datos transferidos, ajustados en un DataObject.allowedEffects
– Uno de los valores de enumeración DragDropEffects que especifica los efectos permitidos de la operación de arrastrar y colocar.
Puede pasar cualquier objeto serializable en el parámetro data
. Si los datos todavía no están ajustados en un DataObject, se ajustarán automáticamente en un DataObject nuevo. Para pasar varios elementos de datos, debe crear por su cuenta el DataObject y pasarlo al método DoDragDrop. Para obtener más información, consulte Datos y objetos de datos.
El parámetro allowedEffects
se usa para especificar lo que el origen de arrastre permitirá que haga el destino de colocación con los datos transferidos. Los valores comunes para un origen de arrastre son Copy, Move y All.
Nota:
El destino de colocación también puede especificar qué efectos desea tener como respuesta a los datos colocados. Por ejemplo, si el destino de colocación no reconoce el tipo de datos que se van a colocar, puede rechazar los datos estableciendo sus efectos permitidos en None. Normalmente lo hace en su controlador de eventos DragOver.
Opcionalmente, un origen de arrastre puede controlar los eventos GiveFeedback y QueryContinueDrag. Estos eventos tienen controladores predeterminados que se usan a menos que marque los eventos como controlados. Normalmente, omitirá estos eventos a menos que necesite cambiar su comportamiento predeterminado.
El evento GiveFeedback se produce continuamente mientras se arrastra el origen de arrastre. El controlador predeterminado de este evento comprueba si el origen de arrastre se encuentra sobre un destino para colocar válido. Si es así, comprueba los efectos permitidos del destino de colocación. A continuación, ofrece información al usuario final sobre los efectos de colocación permitidos. Esto suele hacerse cambiando el cursor del mouse al cursor de mover, copiar o no colocar. Solo se debe controlar este evento si necesita usar cursores personalizados para proporcionar información al usuario. Si controla este evento, asegúrese de marcarlo como controlado para que el controlador predeterminado no invalide el controlador.
El evento QueryContinueDrag se produce continuamente mientras se arrastra el origen de arrastre. Puede controlar este evento para determinar qué acción finaliza la operación de arrastrar y colocar en función del estado de las teclas ESC, MAYÚS, CTRL y ALT, así como el estado de los botones del mouse. El controlador predeterminado para este evento cancela la operación de arrastrar y colocar si se presiona la tecla ESC y coloca los datos si se suelta el botón del mouse.
Precaución
Estos eventos se generan continuamente durante la operación de arrastrar y colocar. Por lo tanto, debe evitar las tareas que consumen muchos recursos en los controladores de eventos. Por ejemplo, use un cursor en caché en lugar de crear un nuevo cursor cada vez que se produzca el evento GiveFeedback.
Habilitar un elemento para que sea un destino de colocación
Un objeto que es un destino de colocación es responsable de:
Especificar que es un destino de colocación válido.
Responder al origen de arrastre cuando se arrastra sobre el destino.
Comprobar que los datos transferidos están en un formato que puede recibir.
Procesar los datos colocados.
Para especificar que un elemento es un destino de colocación, su propiedad AllowDrop se establece en true
. A continuación, se generarán los eventos del destino de colocación en el elemento para que pueda controlarlos. Durante una operación de arrastrar y colocar, se produce la siguiente secuencia de eventos en el destino de colocación:
El evento DragEnter se produce cuando se arrastran los datos dentro de los límites del destino de colocación. Normalmente, este evento se controla para que proporcione una vista previa de los efectos de la operación de arrastrar y colocar, si es adecuado para la aplicación. No establezca la propiedad DragEventArgs.Effects en el evento DragEnter, ya que se sobrescribirá en el evento DragOver.
El ejemplo siguiente muestra el controlador de eventos DragEnter para un elemento Ellipse. Este código muestra una vista previa de los efectos de la operación de arrastrar y colocar guardando el pincel Fill actual. A continuación, usa el método GetDataPresent para comprobar si el DataObject que se está arrastrando sobre la elipse contiene datos de cadena que se pueden convertir en un Brush. Si es así, los datos se extraen mediante el método GetData. A continuación, se convierte en un Brush y se aplica a la elipse. El cambio se revierte en el controlador de eventos DragLeave. Si los datos no se pueden convertir en un Brush, no se lleva a cabo ninguna acción.
private Brush _previousFill = null;
private void ellipse_DragEnter(object sender, DragEventArgs e)
{
Ellipse ellipse = sender as Ellipse;
if (ellipse != null)
{
// Save the current Fill brush so that you can revert back to this value in DragLeave.
_previousFill = ellipse.Fill;
// If the DataObject contains string data, extract it.
if (e.Data.GetDataPresent(DataFormats.StringFormat))
{
string dataString = (string)e.Data.GetData(DataFormats.StringFormat);
// If the string can be converted into a Brush, convert it.
BrushConverter converter = new BrushConverter();
if (converter.IsValid(dataString))
{
Brush newFill = (Brush)converter.ConvertFromString(dataString);
ellipse.Fill = newFill;
}
}
}
}
Private _previousFill As Brush = Nothing
Private Sub Ellipse_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
Dim ellipse = TryCast(sender, Ellipse)
If ellipse IsNot Nothing Then
' Save the current Fill brush so that you can revert back to this value in DragLeave.
_previousFill = ellipse.Fill
' If the DataObject contains string data, extract it.
If e.Data.GetDataPresent(DataFormats.StringFormat) Then
Dim dataString = e.Data.GetData(DataFormats.StringFormat)
' If the string can be converted into a Brush, convert it.
Dim converter As New BrushConverter()
If converter.IsValid(dataString) Then
Dim newFill As Brush = CType(converter.ConvertFromString(dataString), Brush)
ellipse.Fill = newFill
End If
End If
End If
End Sub
El evento DragOver se produce continuamente mientras se arrastran los datos sobre el destino de colocación. Este evento se empareja con el evento GiveFeedback en el origen de arrastre. En el controlador de eventos DragOver, suelen usarse los métodos GetDataPresent y GetData para comprobar si los datos transferidos están en un formato que el destino de colocación puede procesar. También se puede comprobar si está presionada alguna tecla modificadora, lo que normalmente indicará si el usuario pretende realizar una acción de mover o copiar. Una vez realizadas estas comprobaciones, se establece la propiedad DragEventArgs.Effects para que notifique al origen de arrastre qué efectos tendrá la colocación de los datos. El origen de arrastre recibe esta información en los argumentos del evento GiveFeedback y puede establecer un cursor apropiado para proporcionar información al usuario.
El ejemplo siguiente muestra el controlador de eventos DragOver para un elemento Ellipse. Este código comprueba si el DataObject que se está arrastrando sobre la elipse contiene datos de cadena que se pueden convertir en un Brush. Si es así, establece la propiedad DragEventArgs.Effects en Copy. Esto indica al origen de arrastre que los datos se pueden copiar a la elipse. Si los datos no se pueden convertir en un Brush, la propiedad DragEventArgs.Effects se establece en None. Esto indica al origen de arrastre que la elipse no es un destino para colocar válido para los datos.
private void ellipse_DragOver(object sender, DragEventArgs e)
{
e.Effects = DragDropEffects.None;
// If the DataObject contains string data, extract it.
if (e.Data.GetDataPresent(DataFormats.StringFormat))
{
string dataString = (string)e.Data.GetData(DataFormats.StringFormat);
// If the string can be converted into a Brush, allow copying.
BrushConverter converter = new BrushConverter();
if (converter.IsValid(dataString))
{
e.Effects = DragDropEffects.Copy | DragDropEffects.Move;
}
}
}
Private Sub Ellipse_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
e.Effects = DragDropEffects.None
' If the DataObject contains string data, extract it.
If e.Data.GetDataPresent(DataFormats.StringFormat) Then
Dim dataString = e.Data.GetData(DataFormats.StringFormat)
' If the string can be converted into a Brush, convert it.
Dim converter As New BrushConverter()
If converter.IsValid(dataString) Then
e.Effects = DragDropEffects.Copy Or DragDropEffects.Move
End If
End If
End Sub
El evento DragLeave se produce cuando los datos se arrastran fuera de los límites del destino sin colocarse. Este evento se controla para deshacer todo lo que se hizo en el controlador de eventos DragEnter.
El ejemplo siguiente muestra el controlador de eventos DragLeave para un elemento Ellipse. Este código deshace la vista previa que se realizó en el controlador de eventos DragEnter aplicando el Brush guardado a la elipse.
private void ellipse_DragLeave(object sender, DragEventArgs e)
{
Ellipse ellipse = sender as Ellipse;
if (ellipse != null)
{
ellipse.Fill = _previousFill;
}
}
Private Sub Ellipse_DragLeave(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
Dim ellipse = TryCast(sender, Ellipse)
If ellipse IsNot Nothing Then
ellipse.Fill = _previousFill
End If
End Sub
El evento Drop se produce cuando los datos se colocan sobre el destino de colocación; de forma predeterminada, esto ocurre cuando se suelta el botón del mouse. En el controlador de eventos Drop, se usa el método GetData para extraer los datos transferidos desde el DataObject y para realizar cualquier procesamiento de datos que requiere la aplicación. El evento Drop finaliza la operación de arrastrar y colocar.
El ejemplo siguiente muestra el controlador de eventos Drop para un elemento Ellipse. Este código aplica los efectos de la operación de arrastrar y colocar y es similar al código del controlador de eventos DragEnter. Comprueba si el DataObject que se está arrastrando sobre la elipse contiene datos de cadena que se pueden convertir en un Brush. Si es así, el Brush se aplica a la elipse. Si los datos no se pueden convertir en un Brush, no se lleva a cabo ninguna acción.
private void ellipse_Drop(object sender, DragEventArgs e)
{
Ellipse ellipse = sender as Ellipse;
if (ellipse != null)
{
// If the DataObject contains string data, extract it.
if (e.Data.GetDataPresent(DataFormats.StringFormat))
{
string dataString = (string)e.Data.GetData(DataFormats.StringFormat);
// If the string can be converted into a Brush,
// convert it and apply it to the ellipse.
BrushConverter converter = new BrushConverter();
if (converter.IsValid(dataString))
{
Brush newFill = (Brush)converter.ConvertFromString(dataString);
ellipse.Fill = newFill;
}
}
}
}
Private Sub Ellipse_Drop(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
Dim ellipse = TryCast(sender, Ellipse)
If ellipse IsNot Nothing Then
' If the DataObject contains string data, extract it.
If e.Data.GetDataPresent(DataFormats.StringFormat) Then
Dim dataString = e.Data.GetData(DataFormats.StringFormat)
' If the string can be converted into a Brush, convert it.
Dim converter As New BrushConverter()
If converter.IsValid(dataString) Then
Dim newFill As Brush = CType(converter.ConvertFromString(dataString), Brush)
ellipse.Fill = newFill
End If
End If
End If
End Sub
Vea también
.NET Desktop feedback