Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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 WPF UserControl personalizado que representa una forma de círculo. Implementará la funcionalidad en el control para habilitar la transferencia de datos mediante arrastrar y soltar. Por ejemplo, si arrastra desde un control Circle a otro, el color de relleno se copia desde el círculo de origen al círculo de destino. Si arrastra desde un control Circle a TextBox, la representación de cadena del color Fill se copia en TextBox. También creará una aplicación pequeña que contiene dos controles de panel y un TextBox para probar la funcionalidad de arrastrar y soltar. Escribirá código que permita a los paneles procesar los datos de círculo eliminados, lo que le permitirá mover o copiar círculos de la colección Children de un panel al otro.
En este tutorial se ilustran las siguientes tareas:
Cree un control de usuario personalizado.
Habilite el control de usuario para que sea un origen de arrastre.
Habilite el control de usuario para que sea un objetivo de soltar.
Habilite un panel para recibir los datos eliminados del 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 TextBox.
Cree un nuevo 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 de WPF.Abra MainWindow.xaml.
Agregue el marcado siguiente entre las etiquetas de apertura y cierre Grid .
Este marcado crea la interfaz de usuario para 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>
Agregar 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.
Abre Circle.xaml.
Este archivo contendrá los elementos de la interfaz de usuario del control de usuario.
Agregue el siguiente marcado a la raíz Grid para crear un control de usuario simple que tenga un círculo azul como su 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 copia. En Visual Basic, agregue el código siguiente para crear un constructor sin parámetros y un constructor de copia.
Para permitir que el control de usuario se copie, agregue un método de constructor de copia en el archivo de código subyacente. En el control de usuario simplificado Circle, solo copiarás el relleno y el tamaño del control Circle.
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 de apertura Window para crear una referencia de espacio de nombres XML a la aplicación actual.
xmlns:local="clr-namespace:DragDropExample"
En el primer StackPanel, agregue el siguiente CÓDIGO XAML 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 tiene el siguiente aspecto.
<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 arrastrar código fuente en el control de usuario
En esta sección, sobrescribirá el método OnMouseMove e iniciará la operación de arrastrar y soltar.
Si se inicia un arrastre (se presiona un botón del ratón y se mueve el ratón), empaquetas los datos que se transferirán en un componente DataObject. En este caso, el control Circle empaquetará tres elementos de datos; una representación de cadena de su color relleno, una representación doble de su alto y una copia de sí misma.
Para iniciar una operación de arrastrar y colocar
Abra Circle.xaml.cs o Circle.xaml.vb.
Agregue la siguiente OnMouseMove sobrecarga para proporcionar el manejo de clases para el 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 OnMouseMove sobrescripción realiza las siguientes tareas:
Comprueba si se presiona el botón izquierdo del mouse mientras se mueve el mouse.
Empaqueta los datos del círculo en un DataObject. En este caso, el control Círculo empaqueta tres elementos de datos: una representación en 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. Pase los tres parámetros siguientes al DoDragDrop método :
dragSource
– Referencia a este control.data
– El 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 de Círculo y arrástrelo sobre los paneles, el otro círculo y el TextBox. Al arrastrar TextBox, el cursor cambia para indicar que se está moviendo.
Al arrastrar un círculo sobre el TextBox, presione la tecla Ctrl. Observe cómo cambia el cursor para indicar una copia.
Arrastre y coloque un círculo sobre el TextBox. La representación en cadena del color de relleno del círculo se anexa a TextBox.
De forma predeterminada, el cursor cambiará durante una operación de arrastrar y colocar para indicar qué efecto tendrá la colocación de los datos. Puede personalizar los comentarios proporcionados al usuario controlando el GiveFeedback evento y estableciendo un cursor diferente.
Enviar comentarios al usuario
Abra Circle.xaml.cs o Circle.xaml.vb.
Agregue la siguiente OnGiveFeedback sobrecarga para proporcionar el manejo de clases para el evento GiveFeedback.
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 OnGiveFeedback sobrescripción realiza las siguientes tareas:
Presione F5 para compilar y ejecutar la aplicación.
Arrastre uno de los controles de Círculo sobre los paneles, el otro círculo y el TextBox. Tenga en cuenta que los cursores ahora son los cursores personalizados que especificó en la OnGiveFeedback sobrescritura.
Seleccione el texto
green
del TextBox.Arrastre el
green
texto 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 cursor de comentarios siempre se establece mediante el origen de arrastre.
Implementar eventos de destino de arrastre en el control de usuario
En esta sección, especificará que el control de usuario es un destino de arrastre, sobrescribirá los métodos que permiten que el control de usuario sea un destino de arrastre y procesará los datos que se dejan caer en él.
Para permitir que el control de usuario sea un destino de soltar
Abre Circle.xaml.
En la etiqueta de apertura UserControl, agregue AllowDrop propiedad 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 OnDrop llama al método cuando la AllowDrop propiedad se establece en true
y los datos del origen de arrastre se quitan en el control de usuario Circle. En este método, procesará los datos eliminados y los aplicará al Círculo.
Para procesar los datos descartados
Abra Circle.xaml.cs o Circle.xaml.vb.
Agregue la siguiente OnDrop sobrecarga para proporcionar el manejo de clases para el evento Drop.
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 OnDrop sobrescripción realiza las siguientes tareas:
Usa el GetDataPresent método para comprobar si los datos arrastrados contienen un objeto de cadena.
Usa el GetData método para extraer los datos de cadena si está presente.
Utiliza un BrushConverter para intentar convertir la cadena en un Brush.
Si la conversión se realiza correctamente, aplica el pincel al Fill del Ellipse que proporciona la interfaz de usuario del control Circle.
Marca el Drop evento como controlado. Debe marcar el evento drop como controlado para que otros elementos que reciban este evento sepan que el control de usuario Circle lo controló.
Presione F5 para compilar y ejecutar la aplicación.
Seleccione el texto
green
en el TextBox.Arrastre el texto a un control de tipo círculo y colóquelo. El círculo cambia de azul a verde.
Escriba el texto
green
en el TextBox.Seleccione el texto
gre
en el TextBox.Arrástrelo a un control Circle y colóquelo. Observe que el cursor cambia para indicar que se permite soltar, pero el color del círculo no cambia porque
gre
no es un color válido.Arrastre desde el control círculo verde y colóquelo en el control círculo azul. El círculo cambia de azul a verde. Observe que el cursor que se muestra depende de si el TextBox o el círculo son el origen de arrastre.
Establecer la AllowDrop propiedad en true
y procesar los datos eliminados es todo lo que es necesario para permitir que un elemento sea un destino de colocación. Sin embargo, para proporcionar una mejor experiencia de usuario, también debe controlar los eventos DragEnter, DragLeave y DragOver. En estos eventos, puede realizar comprobaciones y proporcionar comentarios adicionales al usuario antes de eliminar los datos.
Cuando los datos son arrastrados sobre el control de usuario Circle, el control debe notificar al origen del arrastre si puede procesar los datos que están siendo arrastrados. Si el control no sabe cómo procesar los datos, debe rechazar la eliminación. Para ello, controlará el evento DragOver y establecerá la propiedad Effects.
Para comprobar que se permite la eliminación de datos
Abra Circle.xaml.cs o Circle.xaml.vb.
Agregue la siguiente OnDragOver sobrecarga para proporcionar el manejo de clases para el evento DragOver.
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 OnDragOver sobrescripción realiza las siguientes tareas:
Presione F5 para compilar y ejecutar la aplicación.
Seleccione el texto
gre
en el TextBox.Arrastre el texto a un control Círculo. Nótese que el cursor ahora cambia para indicar que la acción de soltar no está permitida porque
gre
no es un color válido.
Puede mejorar aún más la experiencia del usuario aplicando una vista previa de la operación de colocación. Para el control de usuario Circle, invalidará los métodos OnDragEnter y OnDragLeave. Cuando los datos se arrastran sobre el control, el fondo Fill actual se guarda en una variable de marcador de posición. A continuación, la cadena se convierte en un pincel y se aplica al Ellipse, que proporciona la interfaz de usuario del círculo. Si los datos se arrastran fuera del círculo sin quitarse, el valor original Fill se vuelve a aplicar al círculo.
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 privada Brush 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 siguiente OnDragEnter sobrecarga para proporcionar el manejo de clases para el evento DragEnter.
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 OnDragEnter sobrescripción realiza las siguientes tareas:
Agregue la siguiente OnDragLeave sobrecarga para proporcionar el manejo de clases para el evento DragLeave.
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 OnDragLeave sobrescripción realiza las siguientes tareas:
Presione F5 para compilar y ejecutar la aplicación.
Seleccione el texto
green
en el TextBox.Arrastre el texto sobre un control circular sin soltarlo. El círculo cambia de azul a verde.
Arrastre el texto fuera del alcance del control 'Circle'. El círculo cambia de verde a azul.
Habilitar un panel para recibir datos arrastrados
En esta sección, habilitará los paneles que hospedan los controles de usuario Circle para que actúen como destinos de colocación para los datos de Circle arrastrados. Implementará código que le permitirá mover un Círculo de un panel a otro, o realizar una copia de un control Círculo manteniendo presionada la tecla Ctrl mientras arrastra y suelta un Círculo.
Abra MainWindow.xaml.
Como se muestra en el siguiente XAML, en cada uno de los controles StackPanel, agrega controladores para los eventos DragOver y Drop. Asigne el nombre al controlador de eventos DragOver,
panel_DragOver
, y asigne el nombre al controlador de eventos Drop,panel_Drop
.De forma predeterminada, los paneles no son destinos de eliminación. Para habilitarlos, agregue la AllowDrop propiedad 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 DragOver eventos.
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 DragOver controlador de eventos realiza las siguientes tareas:
Comprueba que los datos arrastrados contienen los datos "Object" empaquetados en el DataObject control de usuario Circle y pasados en la llamada a DoDragDrop.
Si los datos "Object" están presentes, comprueba si se presiona la tecla Ctrl .
Si se presiona la tecla Ctrl, establece la propiedad Effects en Copy. De lo contrario, establezca la propiedad Effects en Move.
Agregue el código siguiente para el controlador de Drop eventos.
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 Drop controlador de eventos realiza las siguientes tareas:
Comprueba si el Drop evento ya se ha controlado. Por ejemplo, si se suelta un círculo sobre otro círculo que maneja el Drop evento, no desea que el panel que contiene el círculo también lo maneje.
Si el evento Drop no se maneja, comprueba si se presiona la tecla Ctrl
Si se presiona la tecla Ctrl en el momento en que Drop ocurre, realiza una copia del control Circle y la agrega a la colección Children de StackPanel.
Si no se presiona la tecla Ctrl, mueve el círculo de la colección del panel padre a la colección del panel en el que se soltó.
Establece la Effects propiedad para notificar al DoDragDrop método si se realizó una operación de movimiento o copia.
Presione F5 para compilar y ejecutar la aplicación.
Seleccione el texto
green
del TextBox.Arrastre el texto sobre un control círculo y suéltelo.
Arrastre un control de círculo desde el panel izquierdo hasta el panel derecho y suéltelo. El círculo se quita de la Children colección del panel izquierdo y se agrega a la colección Niños del panel derecho.
Arrastre un control Circle desde el panel donde se encuentra hasta el otro panel y suéltelo mientras presiona la tecla Ctrl. El círculo se copia y la copia se agrega a la Children colección del panel receptor.
Consulte también
.NET Desktop feedback