Visual Basic .NET no permite el empleo automático de arrastrar y soltar. Hay que escribir código que inicie una operación de arrastrar y soltar en el control origen y escribir código apara los eventos contenidos en el control de destino. De hecho, la única propiedad que se encuentra relacionada con arrastrar y soltar AllowDrop se debe definir como True para que un control desencadene eventos cuando trabaje como destino de una operación de arrastrar y soltar.
Normalmente, se entenderá que el usuario pretende iniciar una operación de arrastrar y soltar cuando el ratón abandone un control pero, a la vez, mantenga pulsado uno de los botones del ratón. En estos casos, tenemos que crear una nueva instancia de DataObject y rellenarla con los datos contenidos en el control origen (este paso es idéntico a lo que hace cuando copia datos en el Portapapeles e incluye la posibilidad de almacenar los datos en varios formatos).
En el paso siguiente es definir qué efectos de la técnica «arrastrar y soltar» deseas permitir a los usuarios. Para ello, utilizaremos el valor DragDropEffects expresado en bits (los efectos permitidos son: Copy, Move, Scroll, Link y All) y pasaremos este valor y el objeto DataObject al método DoDragDrop del control, que iniciará realmente la operación de arrastrar y soltar. El método DoDragDrop es síncrono y no regresa del mismo hasta que no haya finalizado la operación de arrastrar y soltar (o que haya sido cancelada). El valor devuelto por este método es otro valor DragDropEffect que es el que comunica qué efecto ha sido elegido por el usuario (copiar, mover o desplazar) o será None si la operación ha sido cancelada; si el efecto seleccionado es Move, deberás eliminar los datos seleccionados del control origen.
'---------------------------------------------------------------------- 'Código para que un control actúe como ORIGEN de un Drag And Drop '---------------------------------------------------------------------- '---------------------------------------------------------------------- ' Evento MouseMove '---------------------------------------------------------------------- Private Sub FormMain_MouseMove( _ ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles TextBoxUno.MouseMove, TextBoxDos.MouseMove ' salir si no se ha pulsado ningún botón If e.Button = 0 Then Exit Sub '----------------- ' recuperar el objeto ORIGEN del movimiento ' También se puede utilizar la referencia directa o su nombre ' Ejemplo= Dim txtBoxOrigen As TextBox = TextBoxDos '----------------- Dim textBoxORIGEN As TextBox = CType(sender, TextBox) ' si no hay nada en el control no se puede arrastra nada --> salir If textBoxORIGEN.Text.Length = 0 Then Exit Sub 'Salir si el cursor se encuentra dentro del borde del control If e.X >= 0 And e.X < textBoxORIGEN.Width And e.Y >= 0 And e.Y < textBoxORIGEN.Height Then Exit Sub ' almacenar todo el texto seleccionado o todo el texto si no hay sleceeikon Dim data As New DataObject If textBoxORIGEN.SelectionLength > 0 Then data.SetData(DataFormats.Text, textBoxORIGEN.SelectedText) Else data.SetData(DataFormats.Text, textBoxORIGEN.Text) End If '----------------------------------------- ' iniciar la operación de arrastre ' El método DoDragDrop es síncrono y no regresa del mismo hasta que no ' haya finalizado la operación de arrastrar y soltar (o que haya sido cancelada). ' El valor devuelto por este método es otro valor DragDropEffect que ' es el que comunica que efecto ha sido elegido por el usuario ' (copiar mover o desplazar) o será None si la operación ha sido cancelada. ' Si el efecto es Move, deberá eliminar los datos seleccionad del control origen '----------------------------------------- Dim effect As DragDropEffects = DragDropEffects.Copy Or DragDropEffects.Move effect = textBoxORIGEN.DoDragDrop(data, effect) ' Borrar el texto si es una operacion de desplazamiento If effect = DragDropEffects.Move Then If textBoxORIGEN.SelectionLength > 0 Then textBoxORIGEN.SelectedText = String.Empty Else textBoxORIGEN.Clear() End If End If End Sub
Veamos ahora el código para obtener un control que actúe como destino de la operación de arrastrar y soltar. Los controles que puedan ejercer las labores de destino de la operación de arrastrar y soltar pueden recibir cuatro eventos : DragEnter (el ratón está entrando en el área cliente del control), DragOver (el ratón se está moviendo dentro del control), DragLeave (el ratón está abandonando el control) y DragDrop (el botón del ratón se ha liberado sobre el control). Recuerda que debes configurar la propiedad AllowDrop del control destino como True; en caso contrario, no se desencadenará nunca ninguno de estos eventos .
Los eventos DragEnter, DragOver y DragDrop reciben un objeto DragEventArgs como segundo argumento. Podemos conocer con él los detalles relacionados con la operación de arrastrar y soltar que se esté realizando sin más que consultar sus propiedades de sólo lectura: AllowedEffect (un valor expresado en bits que especifica qué acciones se encuentran disponibles), Data (la instancia DataObject que contienen los datos), KeyState (el estado de las teclas Mayús, Ctrl y Alt y de los botones del ratón) y X e Y (la posición del cursor en coordenadas clientes). La propiedad KeyState expresada en bits no se corresponden con cualquier valor enumerado, por lo que deberá utilizar constantes numéricas: 1 (botón izquierdo), 2 (botón derecho), 4 (tecla Mayús), 8 (tecla Ctrl), 16 (botón central) y 32 (tecla Alt).
La única propiedad que se puede rescribir es Effect, a la que podrá asignar un valor que refleje qué operaciones va a aceptar el control destino. El evento DragEnter, comprobará el formato de los datos que se están arrastrando, los efectos disponibles y el estado de las teclas y de los botones del ratón. Para aceptar la operación de arrastrar y soltar, hay que asignar un valor distinto a None a la propiedad Effect. El siguiente procedimiento muestra la forma en que podrá implementar un controlador de eventos DragEnter que funcione correctamente con un control TextBox
'---------------------------------------------------------------------- ' Evento DragEnter '---------------------------------------------------------------------- Private Sub Form1_DragEnter( _ ByVal sender As Object, ByVal e As DragEventArgs) _ Handles TextBoxUno.DragEnter, TextBoxDos.DragEnter ' Drag & Drop, comprobar con DataFormats If e.Data.GetDataPresent(DataFormats.FileDrop) Then e.Effect = DragDropEffects.Copy End If ' If the Ctrl key was pressed during the drag operation then perform ' a Copy. If not, perform a Move. If (e.Data.GetDataPresent(DataFormats.Text)) Then Select Case e.KeyState Case 1 'No key pressed e.Effect = e.AllowedEffect And DragDropEffects.Move Case 9 'CONTROL key pressed e.Effect = e.AllowedEffect And DragDropEffects.Copy Case Else e.Effect = DragDropEffects.None End Select End If End Sub
También podemos utilizar el evento DragEnter para cambiar el aspecto del control destino (por ejemplo, dibujando un borde especial a su alrededor o modificando su color de fondo). Observa que si realizas alguna de esas operaciones ( cambio de color, etc) hay que restaurar el aspecto original en los controladores de eventos DragLeave y DragDrop.
Cuando el ratón se esté moviendo dentro del área cliente del control destino, recibirá eventos DragOver, pero sólo necesitará atrapar este evento si desea proporcionar distintos efectos de arrastrar y soltar (o desactivar completamente la operación de arrastrar y soltar) para cada una de las áreas que existan en el control.
El evento DragDrop es donde se escribe el código que administre el procesamiento real de los datos. Como vemos en el ejemplo siguiente, obtener los datos que se están soltando resulta similar a efectuar una operación de pegado:
'---------------------------------------------------------------------- ' Evento DragDrop '---------------------------------------------------------------------- Private Sub Form1_DragDrop( _ ByVal sender As Object, _ ByVal e As DragEventArgs) _ Handles TextBoxUno.DragDrop, TextBoxDos.DragDrop ' recuperar el objeto DESTINO del movimiento ' Tambien se puede utilizar la referencia directa o su nombre ' Ejemplo: Dim textBoxDESTINO As TextBox = TextBoxUno Dim textBoxDESTINO As TextBox = CType(sender, TextBox) '---------------------------------------------------- ' Arrastar un nombre de fichero de una ventana de windows '---------------------------------------------------- 'If e.Data.GetDataPresent("FileDrop") Then If e.Data.GetDataPresent(DataFormats.FileDrop) Then ' http://www.elguille.info/NET/vs2005/como/ejecutar_acceso_directo.aspx '------------------------------------------------------------------------ '------------------------------------------------------ ' PARTE UNO - Este codigo genera el nombre completo del fichero ' y lo muestra en el control TextBox ' Ejemplo c:\uno\dos\tres\fichero.jpg '------------------------------------------------------ ' Efecto Visual del cursor (en este caso no se permite el mover) e.Effect = DragDropEffects.Copy Dim nombreCompletoFichero As String = String.Empty nombreCompletoFichero = CType(e.Data.GetData(DataFormats.FileDrop, True), String())(0) 'TextBoxNombreFichero.Text = CType(e.Data.GetData("FileDrop", True), String())(0) textBoxDESTINO.Text = nombreCompletoFichero ''------------------------------------------------------ '' PARTE DOS - Este codigo abre el fichero, lo lee y muestra '' su contendio en un TextBox llamado TextBoxContenido ''------------------------------------------------------ 'Dim sr As System.IO.StreamReader 'Try ' sr = New System.IO.StreamReader(nombreCompletoFichero, System.Text.Encoding.Default) ' TextBoxContenido.Text = sr.ReadToEnd() ' sr.Close() ' 'Cursor al final ' TextBoxContenido.SelectionStart = TextBoxContenido.Text.Length ' TextBoxContenido.ScrollToCaret() 'Catch ex As Exception ' TextBoxContenido.Text = "Error al abrir el fichero:" & Environment.NewLine & ex.Message 'End Try End If '---------------------------------------------------- ' Arrastar un texto de un textBox '---------------------------------------------------- If (e.Data.GetDataPresent(DataFormats.Text, True)) Then ' Efecto Visual del cursor ' Decidir si es una copia o un desplazamiento If CType((e.KeyState And 9), Boolean) Then e.Effect = DragDropEffects.Copy Else e.Effect = DragDropEffects.Move End If ' pegar el texto textBoxDESTINO.Text = e.Data.GetData(DataFormats.Text).ToString End If End Sub
El evento QueryContinueDrag se recibe porel control origen cuando la operación de arrastrar y soltar se esté realizando. Este evento recibe un objeto QueryContinueDragEventArgs, que expone las propiedades KeyState, EscapePressed y Action. El código deberá comprobar las teclas pulsadas y si el usuario ha pulsado la tecla Esc. También deberá asignar uno de los siguientes valores enumerados de DragAction a la propiedad Action: Continue (valor predeterminado), Drop o Cancel. Veamos una implementación típica de este evento:
'---------------------------------------------------------------------- ' Evento QueryContinueDrag '---------------------------------------------------------------------- Private Sub FormMain_QueryContinueDrag( _ ByVal sender As Object, _ ByVal e As System.Windows.Forms.QueryContinueDragEventArgs) _ Handles TextBoxUno.QueryContinueDrag, TextBoxDos.QueryContinueDrag If e.EscapePressed Then e.Action = DragAction.Cancel End Sub
© 1997 - - La Güeb de Joaquín | |||||
Joaquin Medina Serrano
|
|||||
|