2015-12-21 10 views
10

Mi sembra di avere un po 'di problemi. Ho un modulo su cui c'è una treeview. In questa vista ad albero ci sono "cartelle" e "elementi". Sto permettendo all'utente di spostare i nodi/cambiare gerarchia per entrambe le cartelle e gli elementi.effetto trascinamento treeview non funzionante

Sto tentando di cambiare il cursore del mouse quando è attiva un'operazione di trascinamento della selezione, tuttavia sembra che semplicemente non funzioni. Ho cambiato tutti i valori necessari e il cursore del mouse durante i diversi eventi, ma senza risultato.

C'è qualcosa che manca dal codice qui sotto che impedirebbe il comportamento corretto? Fondamentalmente, il cursore visualizzato è sempre il cursore di trascinamento della selezione predefinito (sposta, copia, ecc.). Nota che ho abilitato anche HotTracking sulla vista ad albero per abilitare GiveFeedback e spara/colpisce il punto di interruzione.

[EDIT] - Grazie a Hans per la soluzione. Fondamentalmente, la chiamata DoDragDrop deve essere mirata al controllo desiderato utilizzando il suo FQN. Non importa se il tuo controllo del codice sorgente è quello che attiva l'evento ItemDrag, devi specificarlo esplicitamente. Vedi il codice aggiornato di seguito.

 #region Drag and Drop Methods and Event Handlers 
     /// <summary> 
     /// Performs the necessary actions when the user drags and drops a node around the treeview. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void tv_Terms_DragDrop(object sender, DragEventArgs e) 
     { 
      // Retrieve the client coordinates of the drop location. 
      Point targetPoint = this.tv_Terms.PointToClient(new Point(e.X, e.Y)); 

      // Retrieve the node at the drop location. 
      TreeNode targetNode = this.tv_Terms.GetNodeAt(targetPoint); 

      // confirm that the target node isn't null 
      // (for example if you drag outside the control) 
      if (targetNode != null) 
      { 

       // Retrieve the node that was dragged. 
       TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); 
       TreeNode draggedParentNode = draggedNode.Parent; 

       //PERFORM DB OPERATIONS HERE>> 

       // Expand the node at the location 
       // to show the dropped node. 
       targetNode.Expand(); 
      } 
     } 

     /// <summary> 
     /// Adds the necessary effect when dragging. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void tv_Terms_ItemDrag(object sender, ItemDragEventArgs e) 
     { 
      this.tv_Terms.DoDragDrop(e.Item, DragDropEffects.Move); 
     } 

     /// <summary> 
     /// Adds the necessary effect when dragging. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void tv_Terms_DragEnter(object sender, DragEventArgs e) 
     { 
      if(e.Data.GetDataPresent(typeof(TreeNode)) == true) 
       e.Effect = DragDropEffects.Move; 
     } 

     /// <summary> 
     /// Selects the appropriate node when the user is dragging an item. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void tv_Terms_DragOver(object sender, DragEventArgs e) 
     { 
      //THIS METHOD AUTO-SCROLLS THE TREEVIEW IF YOU REACH THE EDGES... 
      this.tv_Terms.Scroll(); 
      TreeNode node = this.tv_Terms.GetNodeAt(this.tv_Terms.PointToClient(new Point(e.X, e.Y))); 
      if (node != null) 
      { 
       NodeInfo info = node.Tag as NodeInfo; 

       if (!info.IsContainer) 
        node = node.Parent; 

       this.tv_Terms.SelectedNode = node; 
      } 
     } 

     private void tv_Terms_GiveFeedback(object sender, GiveFeedbackEventArgs e) 
     { 
      //I DON'T CARE WHAT TYPE OF DRAG IT IS, ALWAYS USE THE CUSTOM CURSOR. 
      e.UseDefaultCursors = false; 
      Cursor.Current = lastcursor;     
     } 

     //I SET/CACHE THE MOUSE CURSOR HERE 
     private void tv_Terms_MouseDown(object sender, MouseEventArgs e) 
     { 
      TreeNode node = this.tv_Terms.GetNodeAt(e.X, e.Y); 
      if (node != null) 
      { 
       //THIS METHOD CREATES THE CUSTOM CURSOR. 
       Bitmap curs = Helpers.CreateNodeCursorIcon(this.imageList1.Images[node.ImageIndex], node.Text); 
       this.lastcursor = new Cursor(curs.GetHicon()); 
       //I CONFIRM THE PROPER CURSOR BY PLACING THE IMAGE IN A P.B. 
       this.pictureBox1.Image = curs; 
       Cursor.Current = lastcursor; 
      } 

     } 

     #endregion 

risposta

8
DoDragDrop(e.Item, DragDropEffects.Move); 

Si tratta di una sottile bug nel tv_Terms_ItemDrag (metodo), si utilizza il metodo DoDragDrop() del form . Questo è importante nel tuo caso, l'evento GiveFeedback viene attivato sulla sorgente di spostamento , non sulla destinazione di rilascio. In altre parole, l'evento GiveFeedback non si attiva mai. Facile da vedere con il debugger btw, è sufficiente impostare un punto di interruzione sul gestore eventi per vederlo mai eseguito. Correzione:

private void tv_Terms_ItemDrag(object sender, ItemDragEventArgs e) 
    { 
     tv_Terms.DoDragDrop(e.Item, DragDropEffects.Move); 
    } 

Questo metodo è preferibilmente anche quello in cui si desidera creare il cursore. E dovresti essere più discriminante nel gestore di eventi DragEnter in modo che non permetta di eliminare , utilizzare e.Data.GetDataPresent (typeof (TreeNode)) per verificare. E rimuovi le manipolazioni del cursore in DragOver.

+0

stranamente il GiveFeedback si attiva ... ma proverò a specificare la vista ad albero in ItemDrag e vedere se lo fa. – MaxOvrdrv

+0

Oh ... Mio ... Dio! Grazie mille! Ho anche aggiunto il controllo nel DragEnter (ha senso!) ... guarda il post delle domande aggiornato. Grazie mille! :) – MaxOvrdrv

+0

un'altra cosa: dove porterei il cursore alla normalità? – MaxOvrdrv

Problemi correlati