Hace poco que quería poner funcionalidad Drag and Drop en mi proyecto y no me había encontrado con este problema, pero estaba intrigado y realmente quería ver si podía encontrar un método mejor que el descrito en la página a la que vinculó Espero haber comprendido claramente todo lo que quería hacer y, en general, creo que logré resolver el problema de una manera mucho más elegante y simple.
En una nota rápida, para problemas como este sería genial si proporciona algún código para que podamos ver exactamente lo que está tratando de hacer. Digo esto solo porque asumí algunas cosas sobre tu código en mi solución ... así que espero que esté bastante cerca.
Aquí está el código, lo que voy a explicar a continuación:
this.LabelDrag.QueryContinueDrag += new System.Windows.Forms.QueryContinueDragEventHandler(this.LabelDrag_QueryContinueDrag);
this.LabelDrag.MouseDown += new System.Windows.Forms.MouseEventHandler(this.LabelDrag_MouseDown);
this.LabelDrag.MouseUp += new System.Windows.Forms.MouseEventHandler(this.LabelDrag_MouseUp);
this.LabelDrop.DragDrop += new System.Windows.Forms.DragEventHandler(this.LabelDrop_DragDrop);
this.LabelDrop.DragEnter += new System.Windows.Forms.DragEventHandler(this.LabelMain_DragEnter);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void LabelDrop_DragDrop(object sender, DragEventArgs e)
{
LabelDrop.Text = e.Data.GetData(DataFormats.Text).ToString();
}
private void LabelMain_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void LabelDrag_MouseDown(object sender, MouseEventArgs e)
{
//EXTREMELY IMPORTANT - MUST CALL LabelDrag's DoDragDrop method!!
//Calling the Form's DoDragDrop WILL NOT allow QueryContinueDrag to fire!
((Label)sender).DoDragDrop(TextMain.Text, DragDropEffects.Copy);
}
private void LabelDrag_MouseUp(object sender, MouseEventArgs e)
{
LabelDrop.Text = "LabelDrag_MouseUp";
}
private void LabelDrag_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
//Get rect of LabelDrop
Rectangle rect = new Rectangle(LabelDrop.Location, new Size(LabelDrop.Width, LabelDrop.Height));
//If the left mouse button is up and the mouse is not currently over LabelDrop
if (Control.MouseButtons != MouseButtons.Left && !rect.Contains(PointToClient(Control.MousePosition)))
{
//Cancel the DragDrop Action
e.Action = DragAction.Cancel;
//Manually fire the MouseUp event
LabelDrag_MouseUp(sender, new MouseEventArgs(Control.MouseButtons, 0, Control.MousePosition.X, Control.MousePosition.Y, 0));
}
}
}
He dejado fuera la mayor parte del código del diseñador, pero incluyó el enlace Gestor de Eventos Código de lo que puede estar seguro de lo que está ligada a lo que. En mi ejemplo, la función de arrastrar/soltar se produce entre las etiquetas LabelDrag y LabelDrop.
La pieza principal de mi solución es el uso del evento QueryContinueDrag. Este evento se activa cuando el estado del teclado o del mouse cambia después de que DoDragDrop ha sido llamado en ese control. Puede que ya esté haciendo esto, pero es muy importante que llame al método DoDragDrop del control que es su fuente y no al método asociado con el formulario. ¡De lo contrario, QueryContinueDrag NO se disparará!
Una cosa a tener en cuenta es que QueryContinueDrag realmente se disparará cuando suelte el mouse en el control de caída, así que tenemos que asegurarnos de que lo permitamos. Esto se controla comprobando que la posición del mouse (recuperada con la propiedad global Control.MousePosition) está dentro del rectángulo de control LabelDrop. También debe asegurarse de convertir MousePosition en un punto relativo a la ventana del cliente con PointToClient, ya que Control.MousePosition devuelve una posición relativa posición.
, mediante la comprobación de que el ratón es no sobre el control de la caída y que el botón del ratón es ahora hasta hemos capturado con eficacia un evento MouseUp para el control LabelDrag! :) Ahora, puedes hacer cualquier procesamiento que quieras hacer aquí, pero si ya tienes el código que estás usando en el controlador de eventos MouseUp, esto no es eficiente. Así que simplemente llame a su evento MouseUp desde aquí, pasándole los parámetros necesarios y el manejador MouseUp nunca sabrá la diferencia.
Sólo una nota, sin embargo, como lo llamo DoDragDrop de dentro del controlador de eventos MouseDown en mi ejemplo, este código debe nunca se consigue realmente un evento MouseUp directa al fuego. Acabo de poner ese código allí para mostrar que es posible hacerlo.
Espero que ayude!
argh, me he encontrado con este problema también. Bastante molesto si me preguntas! –