Tutorial: Habilitar la técnica de arrastrar y colocar en un control de usuario
En este tutorial se muestra cómo crear un control de usuario personalizado que pueda participar en la transferencia de datos de arrastrar y colocar en Windows Presentation Foundation (WPF).
En este tutorial, creará un objeto UserControl de WPF personalizado que representa una forma circular. Implementará la funcionalidad del control para habilitar la transferencia de datos mediante la técnica de arrastrar y colocar. Por ejemplo, si arrastra de un control de círculo a otro, se copian los datos del color de relleno del círculo de origen al de destino. Si arrastra un control Circle a un objeto TextBox, la representación de cadena del color de relleno se aplica a TextBox. También creará una pequeña aplicación con dos controles de panel y un objeto TextBox para probar la funcionalidad de arrastrar y colocar. Escribirá código para que los paneles puedan procesar los datos del círculo colocado, lo que le permitirá mover o copiar círculos de la colección secundaria de un panel a otro.
En este tutorial se muestran las tareas siguientes:
Crear un control de usuario personalizado.
Permitir que el control de usuario sea un origen de arrastre.
Permitir que el control de usuario sea un destino de colocación.
Permitir que un panel reciba los datos que se colocan desde el control de usuario.
Prerrequisitos
Necesita Visual Studio para completar este tutorial.
Creación del proyecto de aplicación
En esta sección, creará la infraestructura de la aplicación, que incluye una página principal con dos paneles y un objeto TextBox.
Cree un proyecto de aplicación de WPF en Visual Basic o Visual C# denominado
DragDropExample
. Para obtener más información, vea Tutorial: Mi primera aplicación de escritorio WPF.Abra MainWindow.xaml.
Agregue el marcado siguiente en las etiquetas Grid de apertura y cierre.
Este marcado crea la interfaz de usuario de la aplicación de prueba.
<Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <StackPanel Grid.Column="0" Background="Beige"> <TextBox Width="Auto" Margin="2" Text="green"/> </StackPanel> <StackPanel Grid.Column="1" Background="Bisque"> </StackPanel>
Adición de un nuevo control de usuario al proyecto
En esta sección, agregará un nuevo control de usuario al proyecto.
En el menú Proyecto, seleccione Agregar control de usuario.
En el cuadro de diálogo Agregar nuevo elemento, cambie el nombre a
Circle.xaml
y haga clic en Agregar.Circle.xaml y su código subyacente se agregan al proyecto.
Abra Circle.xaml.
Este archivo contendrá los elementos de la interfaz de usuario del control de usuario.
Agregue el marcado siguiente al elemento Grid raíz para crear un control de usuario sencillo que tenga un círculo azul como interfaz de usuario.
<Ellipse x:Name="circleUI" Height="100" Width="100" Fill="Blue" />
Abra Circle.xaml.cs o Circle.xaml.vb.
En C#, agregue el código siguiente después del constructor sin parámetros para crear un constructor de copias. En Visual Basic, agregue el código siguiente para crear un constructor sin parámetros y un constructor de copias.
Para permitir que se copie el control de usuario, puede agregar un método de constructor de copias en el archivo de código subyacente. En el control de usuario de círculo simplificado, solo copiará el relleno y el tamaño del control de usuario.
public Circle(Circle c) { InitializeComponent(); this.circleUI.Height = c.circleUI.Height; this.circleUI.Width = c.circleUI.Height; this.circleUI.Fill = c.circleUI.Fill; }
Public Sub New() ' This call is required by the designer. InitializeComponent() End Sub Public Sub New(ByVal c As Circle) InitializeComponent() Me.circleUI.Height = c.circleUI.Height Me.circleUI.Width = c.circleUI.Height Me.circleUI.Fill = c.circleUI.Fill End Sub
Adición del control de usuario a la ventana principal
Abra MainWindow.xaml.
Agregue el código XAML siguiente a la etiqueta Window de apertura para crear una referencia de espacio de nombres XML a la aplicación actual.
xmlns:local="clr-namespace:DragDropExample"
En el primer objeto StackPanel, agregue el código XAML siguiente para crear dos instancias del control de usuario Circle en el primer panel.
<local:Circle Margin="2" /> <local:Circle Margin="2" />
El código XAML completo del panel tendrá el aspecto siguiente.
<StackPanel Grid.Column="0" Background="Beige"> <TextBox Width="Auto" Margin="2" Text="green"/> <local:Circle Margin="2" /> <local:Circle Margin="2" /> </StackPanel> <StackPanel Grid.Column="1" Background="Bisque"> </StackPanel>
Implementación de eventos de origen de arrastre en el control de usuario
En esta sección, invalidará el método OnMouseMove e iniciará la operación de arrastrar y colocar.
Si se inicia un arrastre (se presiona un botón del mouse y se mueve), empaquetará los datos para que se transfieran a un objeto DataObject. En este caso, el control de círculo empaquetará tres elementos de datos: una representación de cadena de su color de relleno, una representación doble de su altura y una copia de sí mismo.
Para iniciar una operación de arrastrar y colocar
Abra Circle.xaml.cs o Circle.xaml.vb.
Agregue la invalidación de OnMouseMove siguiente para proporcionar control de clases al evento MouseMove.
protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (e.LeftButton == MouseButtonState.Pressed) { // Package the data. DataObject data = new DataObject(); data.SetData(DataFormats.StringFormat, circleUI.Fill.ToString()); data.SetData("Double", circleUI.Height); data.SetData("Object", this); // Initiate the drag-and-drop operation. DragDrop.DoDragDrop(this, data, DragDropEffects.Copy | DragDropEffects.Move); } }
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Input.MouseEventArgs) MyBase.OnMouseMove(e) If e.LeftButton = MouseButtonState.Pressed Then ' Package the data. Dim data As New DataObject data.SetData(DataFormats.StringFormat, circleUI.Fill.ToString()) data.SetData("Double", circleUI.Height) data.SetData("Object", Me) ' Inititate the drag-and-drop operation. DragDrop.DoDragDrop(Me, data, DragDropEffects.Copy Or DragDropEffects.Move) End If End Sub
Esta invalidación de OnMouseMove realiza las tareas siguientes:
Comprueba si el botón primario del mouse está presionado mientras este se mueve.
Empaqueta los datos de Circle en un objeto DataObject. En este caso, el control de círculo empaqueta tres elementos de datos: una representación de cadena de su color de relleno, una representación doble de su altura y una copia de sí mismo.
Llama al método estático DragDrop.DoDragDrop para iniciar la operación de arrastrar y colocar. Debe pasar los tres parámetros siguientes al método DoDragDrop:
dragSource
: una referencia a este control.data
: el objeto DataObject creado en el código anterior.allowedEffects
: las operaciones de arrastrar y colocar permitidas, que son Copy o Move.
Presione F5 para compilar y ejecutar la aplicación.
Haga clic en uno de los controles Circle y arrástrelo sobre los paneles, el otro control Circle y el elemento TextBox. Al arrastrar sobre TextBox, el cursor cambia para indicar un movimiento.
Al arrastrar un control Circle sobre TextBox, presione la tecla Ctrl. Observe que el cursor cambia para indicar una copia.
Arrastre y coloque un control Circle sobre TextBox. La representación de cadena del color de relleno de Circle se anexa al elemento TextBox.
Representación de cadena del color de relleno de CircleDragDrop_ColorString
De forma predeterminada, el cursor cambiará durante una operación de arrastrar y colocar para indicar el efecto que tendrá la colocación de los datos. Puede personalizar la respuesta que se proporciona al usuario si controla el evento GiveFeedback y establece otro cursor.
Respuesta al usuario
Abra Circle.xaml.cs o Circle.xaml.vb.
Agregue la invalidación de OnMouseMove siguiente para proporcionar control de clases al evento MouseMove.
protected override void OnGiveFeedback(GiveFeedbackEventArgs e) { base.OnGiveFeedback(e); // These Effects values are set in the drop target's // DragOver event handler. if (e.Effects.HasFlag(DragDropEffects.Copy)) { Mouse.SetCursor(Cursors.Cross); } else if (e.Effects.HasFlag(DragDropEffects.Move)) { Mouse.SetCursor(Cursors.Pen); } else { Mouse.SetCursor(Cursors.No); } e.Handled = true; }
Protected Overrides Sub OnGiveFeedback(ByVal e As System.Windows.GiveFeedbackEventArgs) MyBase.OnGiveFeedback(e) ' These Effects values are set in the drop target's ' DragOver event handler. If e.Effects.HasFlag(DragDropEffects.Copy) Then Mouse.SetCursor(Cursors.Cross) ElseIf e.Effects.HasFlag(DragDropEffects.Move) Then Mouse.SetCursor(Cursors.Pen) Else Mouse.SetCursor(Cursors.No) End If e.Handled = True End Sub
Esta invalidación de OnMouseMove realiza las tareas siguientes:
Comprueba los valores Effects establecidos en el controlador de eventosDragOver del destino de la operación de colocar.
Establece un curso personalizado en función del valor Effects. El cursor está diseñado para proporcionar información visual al usuario sobre el efecto que tendrá la colocación de los datos.
Presione F5 para compilar y ejecutar la aplicación.
Arrastre uno de los controles Circle sobre los paneles, el otro control Circle y el elemento TextBox. Observe que ahora los cursores son los cursores personalizados que ha especificado en la invalidación de OnGiveFeedback.
Arrastrar y colocar con cursores personalizadosDragDrop_CustomCursor
Seleccione el texto
green
de TextBox.Arrastre el texto
green
a un control de círculo. Observe que los cursores predeterminados se muestran para indicar los efectos de la operación de arrastrar y colocar. El origen de arrastre siempre establece el cursor de retroacción.
Implementación de eventos de destino de colocación en el control de usuario
En esta sección, especificará que el control de usuario es un destino de colocación, invalidará los métodos que permiten que el control de usuario sea un destino de colocación y procesará los datos que se colocan en él.
Para permitir que el control de usuario sea un destino de colocación
Abra Circle.xaml.
En la etiqueta UserControl de apertura, agregue la propiedad AllowDrop y establézcala en
true
.<UserControl x:Class="DragDropWalkthrough.Circle" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" AllowDrop="True">
Se llama al método OnDrop cuando la propiedad AllowDrop se establece en true
y los datos del origen de arrastre se colocan en el control de usuario Circle. En este método, procesará los datos que se han colocado y aplicará los datos al círculo.
Para procesar los datos colocados
Abra Circle.xaml.cs o Circle.xaml.vb.
Agregue la invalidación de OnMouseMove siguiente para proporcionar control de clases al evento MouseMove.
protected override void OnDrop(DragEventArgs e) { base.OnDrop(e); // 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); circleUI.Fill = newFill; // Set Effects to notify the drag source what effect // the drag-and-drop operation had. // (Copy if CTRL is pressed; otherwise, move.) if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey)) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.Move; } } } e.Handled = true; }
Protected Overrides Sub OnDrop(ByVal e As System.Windows.DragEventArgs) MyBase.OnDrop(e) ' If the DataObject contains string data, extract it. If e.Data.GetDataPresent(DataFormats.StringFormat) Then Dim dataString As String = e.Data.GetData(DataFormats.StringFormat) ' If the string can be converted into a Brush, ' convert it and apply it to the ellipse. Dim converter As New BrushConverter If converter.IsValid(dataString) Then Dim newFill As Brush = converter.ConvertFromString(dataString) circleUI.Fill = newFill ' Set Effects to notify the drag source what effect ' the drag-and-drop operation had. ' (Copy if CTRL is pressed; otherwise, move.) If e.KeyStates.HasFlag(DragDropKeyStates.ControlKey) Then e.Effects = DragDropEffects.Copy Else e.Effects = DragDropEffects.Move End If End If End If e.Handled = True End Sub
Esta invalidación de OnMouseMove realiza las tareas siguientes:
Usa el método GetDataPresent para comprobar si los datos arrastrados contienen un objeto de cadena.
Usa el método GetData para extraer los datos de cadena, si existen.
Usa un objeto BrushConverter para intentar convertir la cadena en un objeto Brush.
Si la conversión es correcta, aplica el pincel al objeto Fill del elemento Ellipse que proporciona la interfaz de usuario del control Circle.
Marca el evento Drop como controlado. Debe marcar el evento de colocación como controlado para que los elementos que reciban este evento sepan que el control de usuario de círculo lo ha controlado.
Presione F5 para compilar y ejecutar la aplicación.
Seleccione el texto
green
en TextBox.Arrastre el texto a un control de círculo y colóquelo. El círculo cambia de azul a verde.
Convertir una cadena en pincelDragDrop_DropGreenText
Escriba el texto
green
en TextBox.Seleccione el texto
green
en TextBox.Arrástrelo a un control de círculo y colóquelo. Observe que el cursor cambia para indicar que se permite la colocación, pero el color del círculo no cambia porque
gre
no es un color válido.Arrastre desde el control de círculo verde y coloque en el control de círculo azul. El círculo cambia de azul a verde. Observe que el cursor que se muestra depende de si el origen de arrastre es TextBox o el control Circle.
Lo único necesario para permitir que un elemento sea un destino de colocación es establecer la propiedad AllowDrop en true
y procesar los datos colocados. Pero para proporcionar una experiencia de usuario mejor, también debe controlar los eventos DragEnter, DragLeave y DragOver. En estos eventos, puede realizar comprobaciones y proporcionar repuesta adicional al usuario antes de que se coloquen los datos.
Cuando los datos se arrastran sobre el control de usuario de círculo, el control debe notificarle al origen de arrastre si puede procesar los datos que se están arrastrando. Si el control no sabe cómo procesar los datos, debe rechazar la operación de colocar. Para ello, controlará el evento DragOver y establecerá la propiedad Effects.
Para comprobar que se permite la colocación de datos
Abra Circle.xaml.cs o Circle.xaml.vb.
Agregue la invalidación de OnMouseMove siguiente para proporcionar control de clases al evento MouseMove.
protected override void OnDragOver(DragEventArgs e) { base.OnDragOver(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 or moving. BrushConverter converter = new BrushConverter(); if (converter.IsValid(dataString)) { // Set Effects to notify the drag source what effect // the drag-and-drop operation will have. These values are // used by the drag source's GiveFeedback event handler. // (Copy if CTRL is pressed; otherwise, move.) if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey)) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.Move; } } } e.Handled = true; }
Protected Overrides Sub OnDragOver(ByVal e As System.Windows.DragEventArgs) MyBase.OnDragOver(e) e.Effects = DragDropEffects.None ' If the DataObject contains string data, extract it. If e.Data.GetDataPresent(DataFormats.StringFormat) Then Dim dataString As String = e.Data.GetData(DataFormats.StringFormat) ' If the string can be converted into a Brush, allow copying or moving. Dim converter As New BrushConverter If converter.IsValid(dataString) Then ' Set Effects to notify the drag source what effect ' the drag-and-drop operation will have. These values are ' used by the drag source's GiveFeedback event handler. ' (Copy if CTRL is pressed; otherwise, move.) If e.KeyStates.HasFlag(DragDropKeyStates.ControlKey) Then e.Effects = DragDropEffects.Copy Else e.Effects = DragDropEffects.Move End If End If End If e.Handled = True End Sub
Esta invalidación de OnMouseMove realiza las tareas siguientes:
Presione F5 para compilar y ejecutar la aplicación.
Seleccione el texto
green
en TextBox.Arrastre el texto a un control de círculo. Observe que ahora el cursor cambia para indicar que no se permite la colocación porque
gre
no es un color válido.
Puede mejorar la experiencia del usuario si aplica una vista previa de la operación de colocar. Para el control de usuario Circle, tendrá que invalidar los métodos OnDragEnter y OnDragLeave. Cuando los datos se arrastran sobre el control, el valor Fill del fondo actual se guarda en una variable de marcador de posición. Después, la cadena se convierte en un pincel y se aplica al elemento Ellipse que proporciona la interfaz de usuario de Circle. Si los datos se arrastran fuera del control Circle sin colocarse, se le vuelve a aplicar el valor Fill original.
Para obtener una vista previa de los efectos de la operación de arrastrar y colocar
Abra Circle.xaml.cs o Circle.xaml.vb.
En la clase Circle, declare una variable Brush privada denominada
_previousFill
e inicialícela ennull
.public partial class Circle : UserControl { private Brush _previousFill = null;
Public Class Circle Private _previousFill As Brush = Nothing
Agregue la invalidación de OnMouseMove siguiente para proporcionar control de clases al evento MouseMove.
protected override void OnDragEnter(DragEventArgs e) { base.OnDragEnter(e); // Save the current Fill brush so that you can revert back to this value in DragLeave. _previousFill = circleUI.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.ToString()); circleUI.Fill = newFill; } } }
Protected Overrides Sub OnDragEnter(ByVal e As System.Windows.DragEventArgs) MyBase.OnDragEnter(e) _previousFill = circleUI.Fill ' If the DataObject contains string data, extract it. If e.Data.GetDataPresent(DataFormats.StringFormat) Then Dim dataString As String = 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 = converter.ConvertFromString(dataString) circleUI.Fill = newFill End If End If e.Handled = True End Sub
Esta invalidación de OnMouseMove realiza las tareas siguientes:
Agregue la invalidación de OnMouseMove siguiente para proporcionar control de clases al evento MouseMove.
protected override void OnDragLeave(DragEventArgs e) { base.OnDragLeave(e); // Undo the preview that was applied in OnDragEnter. circleUI.Fill = _previousFill; }
Protected Overrides Sub OnDragLeave(ByVal e As System.Windows.DragEventArgs) MyBase.OnDragLeave(e) ' Undo the preview that was applied in OnDragEnter. circleUI.Fill = _previousFill End Sub
Esta invalidación de OnMouseMove realiza las tareas siguientes:
Presione F5 para compilar y ejecutar la aplicación.
Seleccione el texto
green
en TextBox.Arrastre el texto sobre un control de círculo sin colocarlo. El círculo cambia de azul a verde.
Vista previa de los efectos de una operación de arrastrar y colocarDragDrop_PreviewEffects
Arrastre el texto fuera del control de círculo. El círculo cambia de verde a azul.
Permiso para que un panel reciba datos colocados
En esta sección, habilitará los paneles que hospedan los controles de usuario Circle para que actúen como destinos de colocación de los datos de Circle arrastrados. Implementará código que le permita mover un control Circle de un panel a otro, o bien crear una copia de un control Circle manteniendo presionada la tecla Ctrl mientras arrastra y coloca un control Circle.
Abra MainWindow.xaml.
Como se muestra en el código XAML siguiente, en cada control StackPanel, agregue controladores para los eventos DragOver y Drop. Asigne el nombre
panel_DragOver
al controlador de eventos DragOver, y el nombrepanel_Drop
al controlador de eventos Drop.De manera predeterminada, los paneles no son destinos de colocación. Para habilitarlos, agregue la propiedad AllowDrop a ambos paneles y establezca el valor en
true
.<StackPanel Grid.Column="0" Background="Beige" AllowDrop="True" DragOver="panel_DragOver" Drop="panel_Drop"> <TextBox Width="Auto" Margin="2" Text="green"/> <local:Circle Margin="2" /> <local:Circle Margin="2" /> </StackPanel> <StackPanel Grid.Column="1" Background="Bisque" AllowDrop="True" DragOver="panel_DragOver" Drop="panel_Drop"> </StackPanel>
Abra MainWindows.xaml.cs o MainWindow.xaml.vb.
Agregue el código siguiente para el controlador de eventos DragOver.
private void panel_DragOver(object sender, DragEventArgs e) { if (e.Data.GetDataPresent("Object")) { // These Effects values are used in the drag source's // GiveFeedback event handler to determine which cursor to display. if (e.KeyStates == DragDropKeyStates.ControlKey) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.Move; } } }
Private Sub panel_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs) If e.Data.GetDataPresent("Object") Then ' These Effects values are used in the drag source's ' GiveFeedback event handler to determine which cursor to display. If e.KeyStates = DragDropKeyStates.ControlKey Then e.Effects = DragDropEffects.Copy Else e.Effects = DragDropEffects.Move End If End If End Sub
Este controlador de eventos DragOver realiza las tareas siguientes:
Comprueba que los datos arrastrados contienen los datos "Object" que el control de usuario Circle ha empaquetado en DataObject y se han pasado en la llamada a DoDragDrop.
Si los datos "Object" están presentes, comprueba si se ha presionado la tecla Ctrl.
Si se ha presionado la tecla Ctrl, establece la propiedad Effects en Copy. De lo contrario, la propiedad Effects se establece en Move.
Agregue el código siguiente para el controlador de eventos DragOver.
private void panel_Drop(object sender, DragEventArgs e) { // If an element in the panel has already handled the drop, // the panel should not also handle it. if (e.Handled == false) { Panel _panel = (Panel)sender; UIElement _element = (UIElement)e.Data.GetData("Object"); if (_panel != null && _element != null) { // Get the panel that the element currently belongs to, // then remove it from that panel and add it the Children of // the panel that its been dropped on. Panel _parent = (Panel)VisualTreeHelper.GetParent(_element); if (_parent != null) { if (e.KeyStates == DragDropKeyStates.ControlKey && e.AllowedEffects.HasFlag(DragDropEffects.Copy)) { Circle _circle = new Circle((Circle)_element); _panel.Children.Add(_circle); // set the value to return to the DoDragDrop call e.Effects = DragDropEffects.Copy; } else if (e.AllowedEffects.HasFlag(DragDropEffects.Move)) { _parent.Children.Remove(_element); _panel.Children.Add(_element); // set the value to return to the DoDragDrop call e.Effects = DragDropEffects.Move; } } } } }
Private Sub panel_Drop(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs) ' If an element in the panel has already handled the drop, ' the panel should not also handle it. If e.Handled = False Then Dim _panel As Panel = sender Dim _element As UIElement = e.Data.GetData("Object") If _panel IsNot Nothing And _element IsNot Nothing Then ' Get the panel that the element currently belongs to, ' then remove it from that panel and add it the Children of ' the panel that its been dropped on. Dim _parent As Panel = VisualTreeHelper.GetParent(_element) If _parent IsNot Nothing Then If e.KeyStates = DragDropKeyStates.ControlKey And _ e.AllowedEffects.HasFlag(DragDropEffects.Copy) Then Dim _circle As New Circle(_element) _panel.Children.Add(_circle) ' set the value to return to the DoDragDrop call e.Effects = DragDropEffects.Copy ElseIf e.AllowedEffects.HasFlag(DragDropEffects.Move) Then _parent.Children.Remove(_element) _panel.Children.Add(_element) ' set the value to return to the DoDragDrop call e.Effects = DragDropEffects.Move End If End If End If End If End Sub
Este controlador de eventos DragOver realiza las tareas siguientes:
Comprueba si el evento Drop ya se ha controlado. Por ejemplo, si se coloca un control Circle sobre otro que controla el Drop, no le interesa que el panel que contiene el control Circle también lo controle.
Si no se controla el evento Drop, comprueba si se ha presionado la tecla Ctrl.
Si se ha presionado la tecla Ctrl cuando se produce Drop, crea una copia del control Circle y la agrega a la colección Children de StackPanel.
Si no se ha presionado la tecla Ctrl, mueve el control Circle de la colección Children de su panel principal a la colección Children del panel en el que se ha colocado.
Establece la propiedad Effects para notificar al método DoDragDrop si se ha realizado una operación de movimiento o de copia.
Presione F5 para compilar y ejecutar la aplicación.
Seleccione el texto
green
de TextBox.Arrastre el texto sobre un control de círculo y colóquelo.
Arrastre un control de círculo del panel izquierdo al panel derecho y colóquelo. El control Circle se quita de la colección Children del panel izquierdo y se agrega a la colección Children del panel derecho.
Arrastre un control Circle del panel en el que se encuentra al otro panel y colóquelo mientras presiona la tecla Ctrl. El control Circle se copia y la copia se agrega a la colección Children del panel receptor.
Arrastrar un control Circle mientras se presiona la tecla CTRLDragDrop_PanelDrop
Vea también
.NET Desktop feedback