Control.DoDragDrop Metodo

Definizione

Overload

DoDragDrop(Object, DragDropEffects, Bitmap, Point, Boolean)

Avvia un'operazione di trascinamento.

DoDragDrop(Object, DragDropEffects)

Avvia un'operazione di trascinamento della selezione.

DoDragDrop(Object, DragDropEffects, Bitmap, Point, Boolean)

Avvia un'operazione di trascinamento.

C#
public System.Windows.Forms.DragDropEffects DoDragDrop (object data, System.Windows.Forms.DragDropEffects allowedEffects, System.Drawing.Bitmap? dragImage, System.Drawing.Point cursorOffset, bool useDefaultDragImage);

Parametri

data
Object
allowedEffects
DragDropEffects
dragImage
Bitmap
cursorOffset
Point
useDefaultDragImage
Boolean

Restituisce

Valore dell'enumerazione DragDropEffects che rappresenta l'effetto finale eseguito durante l'operazione di trascinamento della selezione.

Commenti

Il parametro allowedEffects determina quali operazioni di trascinamento possono verificarsi. Se l'operazione di trascinamento deve interagire con le applicazioni in un altro processo, data deve essere una classe gestita di base (String, Bitmapo Metafile) o alcuni Object che implementano ISerializable. data può essere anche qualsiasi Object che implementa IDataObject. dragImage è la bitmap che verrà visualizzata durante l'operazione di trascinamento e cursorOffset specifica la posizione del cursore all'interno di dragImage, ovvero un offset dall'angolo superiore sinistro. Specificare true per useDefaultDragImage usare un'immagine di trascinamento della finestra a più livelli con una dimensione di 96x96; in caso contrario, false. Si noti che i bordi esterni di dragImage vengono uniti se la larghezza o l'altezza dell'immagine supera i 300 pixel.

Poiché DoDragDrop(Object, DragDropEffects, Bitmap, Point, Boolean) esegue sempre il passaggio di moltiplicazione RGB nel calcolo del valore alfa, è consigliabile passare sempre un Bitmap senza fusione alfa premoltiplicata. Non verrà generato alcun errore dal passaggio di un Bitmap con fusione alfa premoltiplicata, ma questo metodo lo moltiplica nuovamente, raddoppiando il valore alfa risultante.

Si applica a

Windows Desktop 9 e altre versioni
Prodotto Versioni
Windows Desktop 7, 8, 9

DoDragDrop(Object, DragDropEffects)

Avvia un'operazione di trascinamento della selezione.

C#
public System.Windows.Forms.DragDropEffects DoDragDrop (object data, System.Windows.Forms.DragDropEffects allowedEffects);

Parametri

data
Object

Dati da trascinare.

allowedEffects
DragDropEffects

Uno dei valori di DragDropEffects.

Restituisce

Valore dell'enumerazione DragDropEffects che rappresenta l'effetto finale eseguito durante l'operazione di trascinamento della selezione.

Esempio

Nell'esempio di codice seguente viene illustrata un'operazione di trascinamento della selezione tra due controlli ListBox. Nell'esempio viene chiamato il metodo DoDragDrop all'avvio dell'azione di trascinamento. L'azione di trascinamento inizia se il mouse è stato spostato più di SystemInformation.DragSize dalla posizione del mouse durante l'evento MouseDown. Il metodo IndexFromPoint viene utilizzato per determinare l'indice dell'elemento da trascinare durante l'evento MouseDown.

L'esempio illustra anche l'uso di cursori personalizzati per l'operazione di trascinamento della selezione. L'esempio richiede che due file di cursore, 3dwarro.cur e 3dwno.cur, esistano nella directory dell'applicazione, rispettivamente per il trascinamento personalizzato e i cursori senza rilascio. I cursori personalizzati verranno utilizzati se è selezionata la UseCustomCursorsCheckCheckBox. I cursori personalizzati vengono impostati nel gestore eventi GiveFeedback.

Lo stato della tastiera viene valutato nel gestore eventi DragOver per il ListBoxdestro, per determinare quale operazione di trascinamento si baserà sullo stato dei tasti MAIUSC, CTRL, ALT o CTRL+ALT. La posizione nel ListBox in cui si verifica l'eliminazione viene determinata anche durante l'evento DragOver. Se i dati da eliminare non sono un String, il DragEventArgs.Effect è impostato su None in DragDropEffects. Infine, lo stato del rilascio viene visualizzato nel DropLocationLabelLabel.

I dati da eliminare per il ListBox corretto sono determinati nel gestore eventi DragDrop e il valore String viene aggiunto nella posizione appropriata nel ListBox. Se l'operazione di trascinamento si sposta all'esterno dei limiti del form, l'operazione di trascinamento della selezione viene annullata nel gestore eventi QueryContinueDrag.

C#
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Snip_DragNDrop
{
    public class Form1 : Form
    {
        private ListBox ListDragSource;
        private ListBox ListDragTarget;
        private CheckBox UseCustomCursorsCheck;
        private Label DropLocationLabel;

        private int indexOfItemUnderMouseToDrag;
        private int indexOfItemUnderMouseToDrop;

        private Rectangle dragBoxFromMouseDown;
        private Point screenOffset;

        private Cursor MyNoDropCursor;
        private Cursor MyNormalCursor;

        // The main entry point for the application.
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        public Form1()
        {
            this.ListDragSource = new ListBox();
            this.ListDragTarget = new ListBox();
            this.UseCustomCursorsCheck = new CheckBox();
            this.DropLocationLabel = new Label();

            this.SuspendLayout();

            // ListDragSource
            this.ListDragSource.Items.AddRange(new object[] {"one", "two", "three", "four",
                                                             "five", "six", "seven", "eight",
                                                             "nine", "ten"});
            this.ListDragSource.Location = new Point(10, 17);
            this.ListDragSource.Size = new Size(120, 225);
            this.ListDragSource.MouseDown += this.ListDragSource_MouseDown;
            this.ListDragSource.QueryContinueDrag += this.ListDragSource_QueryContinueDrag;
            this.ListDragSource.MouseUp += this.ListDragSource_MouseUp;
            this.ListDragSource.MouseMove += this.ListDragSource_MouseMove;
            this.ListDragSource.GiveFeedback += this.ListDragSource_GiveFeedback;

            // ListDragTarget
            this.ListDragTarget.AllowDrop = true;
            this.ListDragTarget.Location = new Point(154, 17);
            this.ListDragTarget.Size = new Size(120, 225);
            this.ListDragTarget.DragOver += this.ListDragTarget_DragOver;
            this.ListDragTarget.DragDrop += this.ListDragTarget_DragDrop;
            this.ListDragTarget.DragEnter += this.ListDragTarget_DragEnter;
            this.ListDragTarget.DragLeave += this.ListDragTarget_DragLeave;

            // UseCustomCursorsCheck
            this.UseCustomCursorsCheck.Location = new Point(10, 243);
            this.UseCustomCursorsCheck.Size = new Size(137, 24);
            this.UseCustomCursorsCheck.Text = "Use Custom Cursors";

            // DropLocationLabel
            this.DropLocationLabel.Location = new Point(154, 245);
            this.DropLocationLabel.Size = new Size(137, 24);
            this.DropLocationLabel.Text = "None";

            // Form1
            this.ClientSize = new Size(292, 270);
            this.Controls.AddRange(new Control[] {
                this.ListDragSource,
                this.ListDragTarget,
                this.UseCustomCursorsCheck,
                this.DropLocationLabel});
            this.Text = "drag-and-drop Example";

            this.ResumeLayout(false);
        }

        private void ListDragSource_MouseDown(object sender, MouseEventArgs e)
        {
            // Get the index of the item the mouse is below.
            indexOfItemUnderMouseToDrag = ListDragSource.IndexFromPoint(e.X, e.Y);

            if (indexOfItemUnderMouseToDrag != ListBox.NoMatches)
            {
                // Remember the point where the mouse down occurred. The DragSize indicates
                // the size that the mouse can move before a drag event should be started.
                Size dragSize = SystemInformation.DragSize;

                // Create a rectangle using the DragSize, with the mouse position being
                // at the center of the rectangle.
                dragBoxFromMouseDown = new Rectangle(
                    new Point(e.X - (dragSize.Width / 2),
                              e.Y - (dragSize.Height / 2)),
                    dragSize);
            }
            else
            {
                // Reset the rectangle if the mouse is not over an item in the ListBox.
                dragBoxFromMouseDown = Rectangle.Empty;
            }
        }

        private void ListDragSource_MouseUp(object sender, MouseEventArgs e)
        {
            // Reset the drag rectangle when the mouse button is raised.
            dragBoxFromMouseDown = Rectangle.Empty;
        }

        private void ListDragSource_MouseMove(object sender, MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                // If the mouse moves outside the rectangle, start the drag.
                if (dragBoxFromMouseDown != Rectangle.Empty &&
                    !dragBoxFromMouseDown.Contains(e.X, e.Y))
                {
                    // Create custom cursors for the drag-and-drop operation.
                    try
                    {
                        MyNormalCursor = new Cursor("3dwarro.cur");
                        MyNoDropCursor = new Cursor("3dwno.cur");
                    }
                    catch
                    {
                        // An error occurred while attempting to load the cursors, so use
                        // standard cursors.
                        UseCustomCursorsCheck.Checked = false;
                    }
                    finally
                    {
                        // The screenOffset is used to account for any desktop bands 
                        // that may be at the top or left side of the screen when 
                        // determining when to cancel the drag drop operation.
                        screenOffset = SystemInformation.WorkingArea.Location;

                        // Proceed with the drag-and-drop, passing in the list item.
                        DragDropEffects dropEffect = ListDragSource.DoDragDrop(ListDragSource.Items[indexOfItemUnderMouseToDrag], DragDropEffects.All | DragDropEffects.Link);

                        // If the drag operation was a move then remove the item.
                        if (dropEffect == DragDropEffects.Move)
                        {
                            ListDragSource.Items.RemoveAt(indexOfItemUnderMouseToDrag);

                            // Selects the previous item in the list as long as the list has an item.
                            if (indexOfItemUnderMouseToDrag > 0)
                                ListDragSource.SelectedIndex = indexOfItemUnderMouseToDrag - 1;

                            else if (ListDragSource.Items.Count > 0)
                                // Selects the first item.
                                ListDragSource.SelectedIndex = 0;
                        }

                        // Dispose of the cursors since they are no longer needed.
                        if (MyNormalCursor != null)
                            MyNormalCursor.Dispose();

                        if (MyNoDropCursor != null)
                            MyNoDropCursor.Dispose();
                    }
                }
            }
        }
        private void ListDragSource_GiveFeedback(object sender, GiveFeedbackEventArgs e)
        {
            // Use custom cursors if the check box is checked.
            if (UseCustomCursorsCheck.Checked)
            {
                // Sets the custom cursor based upon the effect.
                e.UseDefaultCursors = false;
                if ((e.Effect & DragDropEffects.Move) == DragDropEffects.Move)
                    Cursor.Current = MyNormalCursor;
                else
                    Cursor.Current = MyNoDropCursor;
            }
        }
        private void ListDragTarget_DragOver(object sender, DragEventArgs e)
        {
            // Determine whether string data exists in the drop data. If not, then
            // the drop effect reflects that the drop cannot occur.
            if (!e.Data.GetDataPresent(typeof(System.String)))
            {
                e.Effect = DragDropEffects.None;
                DropLocationLabel.Text = "None - no string data.";
                return;
            }

            // Set the effect based upon the KeyState.
            if ((e.KeyState & (8 + 32)) == (8 + 32) &&
                (e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link)
            {
                // KeyState 8 + 32 = CTRL + ALT

                // Link drag-and-drop effect.
                e.Effect = DragDropEffects.Link;
            }
            else if ((e.KeyState & 32) == 32 &&
                (e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link)
            {
                // ALT KeyState for link.
                e.Effect = DragDropEffects.Link;
            }
            else if ((e.KeyState & 4) == 4 &&
                (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
            {
                // SHIFT KeyState for move.
                e.Effect = DragDropEffects.Move;
            }
            else if ((e.KeyState & 8) == 8 &&
                (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
            {
                // CTRL KeyState for copy.
                e.Effect = DragDropEffects.Copy;
            }
            else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
            {
                // By default, the drop action should be move, if allowed.
                e.Effect = DragDropEffects.Move;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }

            // Get the index of the item the mouse is below. 

            // The mouse locations are relative to the screen, so they must be 
            // converted to client coordinates.

            indexOfItemUnderMouseToDrop =
                ListDragTarget.IndexFromPoint(ListDragTarget.PointToClient(new Point(e.X, e.Y)));

            // Updates the label text.
            if (indexOfItemUnderMouseToDrop != ListBox.NoMatches)
            {
                DropLocationLabel.Text = "Drops before item #" + (indexOfItemUnderMouseToDrop + 1);
            }
            else
            {
                DropLocationLabel.Text = "Drops at the end.";
            }
        }
        private void ListDragTarget_DragDrop(object sender, DragEventArgs e)
        {
            // Ensure that the list item index is contained in the data.
            if (e.Data.GetDataPresent(typeof(System.String)))
            {
                Object item = e.Data.GetData(typeof(System.String));

                // Perform drag-and-drop, depending upon the effect.
                if (e.Effect == DragDropEffects.Copy ||
                    e.Effect == DragDropEffects.Move)
                {
                    // Insert the item.
                    if (indexOfItemUnderMouseToDrop != ListBox.NoMatches)
                        ListDragTarget.Items.Insert(indexOfItemUnderMouseToDrop, item);
                    else
                        ListDragTarget.Items.Add(item);
                }
            }
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
        private void ListDragSource_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
        {
            // Cancel the drag if the mouse moves off the form.
            ListBox lb = sender as ListBox;

            if (lb != null)
            {
                Form f = lb.FindForm();

                // Cancel the drag if the mouse moves off the form. The screenOffset
                // takes into account any desktop bands that may be at the top or left
                // side of the screen.
                if (((Control.MousePosition.X - screenOffset.X) < f.DesktopBounds.Left) ||
                    ((Control.MousePosition.X - screenOffset.X) > f.DesktopBounds.Right) ||
                    ((Control.MousePosition.Y - screenOffset.Y) < f.DesktopBounds.Top) ||
                    ((Control.MousePosition.Y - screenOffset.Y) > f.DesktopBounds.Bottom))
                {
                    e.Action = DragAction.Cancel;
                }
            }
        }
        private void ListDragTarget_DragEnter(object sender, DragEventArgs e)
        {
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
        private void ListDragTarget_DragLeave(object sender, EventArgs e)
        {
            // Reset the label text.
            DropLocationLabel.Text = "None";
        }
    }
}

Nell'esempio di codice seguente viene illustrato come utilizzare l'enumerazione DragDropEffects per specificare come trasferire i dati tra i controlli coinvolti in un'operazione di trascinamento della selezione. Questo esempio richiede che il form includa un controllo RichTextBox e un controllo ListBox e che il controllo ListBox sia popolato con un elenco di nomi di file validi. Quando l'utente trascina un nome di file nel controllo RichTextBox, viene generato l'evento DragEnter del controllo. All'interno del gestore eventi, la proprietà Effect del DragEventArgs viene inizializzata per DragDropEffects per indicare che i dati a cui fa riferimento il percorso del file devono essere copiati nel controllo RichTextBox.

C#
private void Form1_Load(object sender, EventArgs e) 
{
   // Sets the AllowDrop property so that data can be dragged onto the control.
   richTextBox1.AllowDrop = true;

   // Add code here to populate the ListBox1 with paths to text files.
}

private void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
   // Determines which item was selected.
   ListBox lb =( (ListBox)sender);
   Point pt = new Point(e.X,e.Y);
   int index = lb.IndexFromPoint(pt);

   // Starts a drag-and-drop operation with that item.
   if(index>=0) 
   {
      lb.DoDragDrop(lb.Items[index].ToString(), DragDropEffects.Link);
   }
}

private void richTextBox1_DragEnter(object sender, DragEventArgs e) 
{
   // If the data is text, copy the data to the RichTextBox control.
   if(e.Data.GetDataPresent("Text"))
      e.Effect = DragDropEffects.Copy;
}

private void richTextBox1_DragDrop(object sender, DragEventArgs e) 
{
   // Loads the file into the control. 
   richTextBox1.LoadFile((String)e.Data.GetData("Text"), System.Windows.Forms.RichTextBoxStreamType.RichText);
}

Commenti

Il parametro allowedEffects determina quali operazioni di trascinamento possono verificarsi. Se l'operazione di trascinamento deve interagire con le applicazioni in un altro processo, i dati devono essere una classe gestita di base (String, Bitmapo Metafile) o un oggetto che implementa ISerializable o IDataObject.

Di seguito viene descritto come e quando vengono generati eventi correlati alle operazioni di trascinamento della selezione.

Il metodo DoDragDrop determina il controllo sotto la posizione corrente del cursore. Controlla quindi se il controllo è una destinazione di rilascio valida.

Se il controllo è una destinazione di rilascio valida, l'evento GiveFeedback viene generato con l'effetto di trascinamento della selezione specificato. Per un elenco degli effetti di trascinamento della selezione, vedere l'enumerazione DragDropEffects.

Vengono rilevate modifiche alla posizione del cursore del mouse, allo stato della tastiera e al pulsante del mouse.

  • Se l'utente si sposta all'esterno di una finestra, viene generato l'evento DragLeave.

  • Se il mouse entra in un altro controllo, viene generato il DragEnter per tale controllo.

  • Se il mouse si sposta ma rimane all'interno dello stesso controllo, viene generato l'evento DragOver.

Se si verifica una modifica dello stato della tastiera o del pulsante del mouse, viene generato l'evento QueryContinueDrag e determina se continuare il trascinamento, rilasciare i dati o annullare l'operazione in base al valore della proprietà Action dell'evento QueryContinueDragEventArgs.

  • Se il valore di DragAction è Continue, l'evento DragOver viene generato per continuare l'operazione e l'evento GiveFeedback viene generato con il nuovo effetto in modo che sia possibile impostare il feedback visivo appropriato. Per un elenco di effetti di rilascio validi, vedere l'enumerazione DragDropEffects.

    Nota

    Gli eventi DragOver e GiveFeedback vengono associati in modo che quando il mouse si sposta attraverso la destinazione di rilascio, all'utente viene assegnato il feedback più up-to-date sulla posizione del mouse.

  • Se il valore di DragAction è Drop, il valore dell'effetto di rilascio viene restituito all'origine, in modo che l'applicazione di origine possa eseguire l'operazione appropriata sui dati di origine; Ad esempio, tagliare i dati se l'operazione è stata spostata.

  • Se il valore di DragAction è Cancel, viene generato l'evento DragLeave.

Nota

Il metodo DoDragDrop intercetta tutte le eccezioni e genera nuovamente solo le eccezioni di sicurezza o critiche seguenti:

  • SecurityException

  • NullReferenceException

  • StackOverflowException

  • OutOfMemoryException

  • ThreadAbortException

  • ExecutionEngineException

  • IndexOutOfRangeException

  • AccessViolationException

Vedi anche

Si applica a

.NET Framework 4.8.1 e altre versioni
Prodotto Versioni
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
Windows Desktop 3.0, 3.1, 5, 6, 7, 8, 9