Frage

Gibt es eine einfache Möglichkeit sicherzustellen, dass das MouseUp-Ereignis nach einem fehlgeschlagenen Drag-and-Drop-Vorgang nicht aufgebraucht und vom Framework ignoriert wird?

Ich habe einen Blog-Beitrag gefunden, der es beschreibt ein Mechanismus, aber es erfordert viel manuelle Buchhaltung, einschließlich Statusflags, MouseMove-Ereignisse, manuelle Überprüfung der „Maus verlassen“ usw.All das möchte ich lieber nicht umsetzen, wenn es vermeidbar ist.

War es hilfreich?

Lösung

Ich wollte vor Kurzem die Drag-and-Drop-Funktionalität in mein Projekt integrieren und hatte dieses Problem noch nicht, aber ich war neugierig und wollte unbedingt sehen, ob ich eine bessere Methode als die auf der von Ihnen verlinkten Seite beschriebene finden könnte Zu.Ich hoffe, ich habe alles klar verstanden, was Sie tun wollten, und insgesamt denke ich, dass es mir gelungen ist, das Problem auf viel elegantere und einfachere Weise zu lösen.

Nebenbei bemerkt: Bei Problemen wie diesem wäre es großartig, wenn Sie Code bereitstellen würden, damit wir genau sehen können, was Sie tun möchten.Ich sage das nur, weil ich in meiner Lösung ein paar Dinge über Ihren Code angenommen habe ... also hoffe ich, dass es ziemlich nah dran ist.

Hier ist der Code, den ich im Folgenden erläutern werde:

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));
        }
    }

}

Ich habe den größten Teil des Designer-Codes weggelassen, aber den Event-Handler-Link-Up-Code eingefügt, damit Sie sicher sein können, was mit was verknüpft ist.In meinem Beispiel erfolgt das Drag/Drop zwischen den Labels LabelDrag und LabelDrop.

Der Hauptteil meiner Lösung ist die Verwendung des QueryContinueDrag-Ereignisses.Dieses Ereignis wird ausgelöst, wenn sich der Tastatur- oder Mausstatus ändert, nachdem DoDragDrop für dieses Steuerelement aufgerufen wurde.Möglicherweise tun Sie dies bereits, es ist jedoch sehr wichtig, dass Sie die DoDragDrop-Methode des Steuerelements aufrufen, das Ihre Quelle ist, und nicht die mit dem Formular verknüpfte Methode.Andernfalls wird QueryContinueDrag NICHT ausgelöst!

Zu beachten ist, dass QueryContinueDrag tatsächlich ausgelöst wird, wenn Sie die Maustaste loslassen auf der Drop-Steuerung Deshalb müssen wir sicherstellen, dass wir dies zulassen.Dies wird dadurch gehandhabt, dass überprüft wird, ob die Mausposition (abgerufen mit der globalen Control.MousePosition-Eigenschaft) innerhalb des LabelDrop-Steuerrechtecks ​​liegt.Sie müssen außerdem sicherstellen, dass MousePosition mit PointToClient in einen Punkt relativ zum Clientfenster konvertiert wird, da Control.MousePosition a zurückgibt Bildschirm relativ Position.

Überprüfen Sie also, ob die Maus vorhanden ist nicht über dem Drop-Steuerelement und dass die Maustaste jetzt gedrückt ist hoch Wir haben effektiv ein MouseUp-Ereignis für das LabelDrag-Steuerelement erfasst!:) Nun könnten Sie hier einfach die Verarbeitung durchführen, die Sie möchten, aber wenn Sie bereits Code haben, den Sie im MouseUp-Ereignishandler verwenden, ist dies nicht effizient.Rufen Sie also einfach von hier aus Ihr MouseUp-Ereignis auf und übergeben Sie ihm die erforderlichen Parameter. Der MouseUp-Handler wird den Unterschied nie bemerken.

Nur eine Anmerkung, da ich DoDragDrop aufrufe innerhalb Der MouseDown-Ereignishandler in meinem Beispiel sollte dieser Code sein niemals tatsächlich ein direktes MouseUp-Ereignis zum Auslösen bringen.Ich habe diesen Code nur dort eingefügt, um zu zeigen, dass es möglich ist.

Hoffentlich hilft das!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top