Introduzione.
Spero che tu abbia trovato il tutorial della scorsa settimana su ImageCombo Control utile per i tuoi progetti Microsoft Access. Con il controllo TreeView ImageCombo, potremmo creare un bellissimo menu a discesa, con diverse opzioni, e sistemarlo in un piccolo spazio sul modulo.
Allo stesso modo, in una sessione precedente, abbiamo appreso come aggiungere nuovi nodi in una posizione specifica nella gerarchia dei nodi o come eliminare un nodo e aggiungerne uno nuovo per riposizionare un nodo sul controllo della visualizzazione ad albero.
Questo metodo richiede la creazione di un nuovo record nella tabella di origine per il nuovo nodo. Oppure elimina un record esistente e creane uno nuovo per spostare un nodo esistente e renderlo permanente. In un certo senso, con l'uso delle funzioni Aggiungi/Cancella, potremmo aggiungere nuovi nodi o riorganizzare i nodi esistenti sul controllo TreeView. Per quanto riguarda la riorganizzazione dei nodi, abbiamo un modo migliore per farlo, piuttosto che eliminare i nodi e ricrearli. Trascina il nodo dalla sua posizione corrente e rilascialo dove vogliamo che sia sul controllo TreeView. Questo è ciò che impareremo in questo episodio
Questo semplice approccio richiede solo l'aggiornamento della modifica del valore del campo ParentID dei record correlati, per rendere permanente la modifica.
Gli argomenti trattati finora nelle sessioni precedenti.
- Esercitazione sul controllo di Microsoft TreeView
- Creazione del menu di accesso con il controllo TreeView
- Assegnazione di immagini al controllo TreeView
- Assegnazione di immagini a TreeView Control-2
- Segnale di spunta Controllo TreeView Aggiungi Elimina nodi
- Menu di accesso a discesa TreeView ImageCombo
Tuttavia, potremmo dover affrontare alcune sfide durante l'utilizzo di questo metodo e ci arriveremo poco più avanti in questa Sessione.
Tabella e modulo dati demo.
Abbiamo bisogno di una tabella e di un modulo. Abbiamo già una tabella adatta con il nome Campione creato in una precedente sessione tutorial. Se hai già scaricato il Database Demo, dalla seconda Pagina di collegamento sopra indicata in precedenza, puoi utilizzare quel Database anche per questa Sessione. Useremo i seguenti oggetti da quel database per i nostri esperimenti Drag-Drop:
- Tabella:Campione
- Modulo:frmSample
L'immagine di controllo TreeView su frmSample con dati demo è riportata di seguito come riferimento:
Puoi scaricare il database demo (ProjectMenu.zip ) dalla Second Link Page di cui sopra ed estrarre il ProjectMenu.accdb Banca dati.
Nuovo modulo per le prove di trascinamento della selezione.
-
Apri il database ProjectMenu.accdb.
-
Crea una copia della tabella Campione e denominalo come Sample_bk, tienilo al sicuro, avremo bisogno dei suoi dati originali senza modifiche in seguito. Quando sperimentiamo il metodo drag-drop è necessario aggiornare il valore del campo ParentId sulla tabella dimostrativa del campione. Ma abbiamo bisogno dei dati originali in un secondo momento, senza queste modifiche.
-
Crea un nuovo modulo con il nome frmDragDrop .
-
Il design del modulo frmDragDrop apparirà come l'immagine riportata di seguito al termine.
-
Inserisci il controllo TreeView dall'elenco dei controlli ActiveX e posizionalo sul modulo, lasciando abbastanza spazio sopra il controllo, in modo da poter creare due pulsanti di comando e un'etichetta di intestazione sopra di esso. Trascina la maniglia di ridimensionamento nell'angolo in basso a destra per renderla abbastanza grande da visualizzare tutti i nodi, senza scorrere.
-
Cambia il Nome Valore della proprietà di TreeView Control su TreeView0 .
-
Inserire un pulsante di comando sopra e il bordo sinistro del controllo TreeView. Cambia il suo Nome Valore della proprietà su cmdExpand e Didascalia valore a Espandi tutto .
- Inserisci un secondo pulsante di comando sopra e sul bordo destro del controllo TreeView. Cambia il suo Nome Valore della proprietà su cmdCollapse e la Didascalia Valore della proprietà su Comprimi tutto.
-
Inserisci un controllo etichetta sopra i pulsanti di comando, abbastanza largo da scrivere l'intestazione come mostrato sopra e cambia la dimensione del carattere 14.
-
Ignora il controllo ImageList, per il momento ho commentato le righe di codice che modificano i numeri di indice di Node ImageList. Successivamente, puoi importare il controllo ImageList con immagini caricate manualmente, dal nostro precedente database demo Tutorial (dalla 4a pagina di collegamento indicata sopra) e utilizzarlo per visualizzare le immagini dei nodi sui nodi. Quando le posizioni dei nodi vengono modificate durante le azioni di trascinamento della selezione, è necessario modificare le immagini dei nodi anche in base alla posizione del nodo (nodo a livello di radice o nodo figlio) sul controllo TreeView.
Codice modulo modulo trascinamento.
-
Visualizza il modulo codice VBA del modulo frmDragDrop, copia e incolla il seguente codice VBA (questa è solo la prima metà del codice modulo modulo) nel modulo classe del modulo frmDragDrop e salva il modulo:
Option Compare Database Option Explicit Dim tv As MSComctlLib.TreeView Dim db As DAO.Database Dim rst As DAO.Recordset Dim imgListObj As MSComctlLib.ImageList Const KeyPrfx As String = "X" Private Sub Form_Open(Cancel As Integer) Set tv = Me.TreeView0.Object 'Set imgListObj = Me.ImageList1.Object 'tv.ImageList = imgListObj LoadTreeView End Sub Sub LoadTreeView() Dim strKey As String Dim strPKey As String Dim strText As String Dim strsQL As String strsQL = "SELECT * FROM Sample ORDER BY ID" Set db = CurrentDb Set rst = db.OpenRecordset(strsQL, dbOpenDynaset) tv.Nodes.Clear 'Add all Items are added as Root Nodes Do While Not rst.BOF And Not rst.EOF strKey = KeyPrfx & CStr(rst!ID) strText = rst!desc tv.Nodes.Add , , strKey, strText 'With tv.Nodes.Item(strKey) ' .Image = 1 ' .SelectedImage = 4 'End With rst.MoveNext Loop 'Prepare to update the Parent-Key of Nodes 'wherever applicable to move and position the Child Nodes strPKey = "" rst.MoveFirst Do While Not rst.EOF strPKey = Nz(rst!parentid, "") If Len(strPKey) > 0 Then strPKey = KeyPrfx & strPKey strKey = KeyPrfx & CStr(rst!ID) strText = rst!desc 'Move the Child Node under it's Parent-Node Set tv.Nodes.Item(strKey).Parent = tv.Nodes.Item(strPKey) 'Update Image and SelectedImage Properties 'with ImageList Index numbers 'With tv.Nodes.Item(strKey) ' .Image = 2 ' .SelectedImage = 3 'End With End If rst.MoveNext Loop rst.Close Set rst = Nothing Set db = Nothing End Sub Private Sub TreeView0_NodeClick(ByVal Node As Object) Dim SelectionNode As MSComctlLib.Node 'Ensure that the clicked node equals the selected node in the tree If Not Node Is Nothing Then Set SelectionNode = Node If SelectionNode.Expanded = True Then SelectionNode.Expanded = False Else SelectionNode.Expanded = True End If End If End Sub Private Sub cmdCollapse_Click() Dim tmpnod As MSComctlLib.Node For Each tmpnod In tv.Nodes If tmpnod.Expanded = True Then tmpnod.Expanded = False End If Next End Sub Private Sub cmdExpand_Click() Dim tmpnod As MSComctlLib.Node For Each tmpnod In tv.Nodes If tmpnod.Expanded = False Then tmpnod.Expanded = True End If Next End Sub
So che conosci il codice di cui sopra, se hai già esaminato gli episodi precedenti, ad eccezione di LoadTreeView() sottoprogramma con alcune modifiche. Qui, la compilazione dei nodi TreeView è stata suddivisa in un processo in due fasi.
In breve, questo è ciò che accade in questa subroutine.
Tutti i record su Campione Le tabelle sono state caricate come nodi a livello radice di TreeView Control, con un valore di campo ID come chiave, nel primo passaggio.
Anche in questo caso, questi record sono stati letti una seconda volta e hanno verificato la presenza di un valore in ParentId campo, se vuoto, il nodo verrà mantenuto come nodo a livello di radice.
Se il campo ParentID ha un Valore, identifica il Nodo con il valore ParentID come Node-Key e sposta il nodo corrente come suo nodo figlio, o il suo [Relativo] Parametro (di Aggiungi () Metodo) il valore viene aggiornato.
-
Anche se sembra che la procedura di popolamento dei nodi in due passaggi sia un esercizio non necessario, c'è una buona ragione per cui dobbiamo seguire questo metodo. Torneremo su questo poco dopo e lo saprai senza molte spiegazioni.
-
Sulla progettazione del modulo, ho fornito un controllo ImageList. Puoi inserire il controllo ActiveX ImageList e carica alcune immagini manualmente dal disco, oppure copia e incolla questo controllo con le immagini dei download di database demo precedenti. In entrambi i casi, assicurati che il nome del controllo ImageList sia ImageList1 . In caso contrario, è necessario modificare il nome nel codice.
-
Successivamente, abilita le righe commentate in Form_Open() Event Procedure. Abilita le seguenti righe, rimuovendo il simbolo del commento dall'inizio della riga:
'Set imgListObj = Me.ImageList1.Object 'tv.ImageList = imgListObj
-
Nella TreeView0_ OLEDragDrop() La subroutine (nella seconda parte del codice VBA) abilita i parametri dell'indice di immagine dei nodi, rimuovendo anche i simboli di commento da quelle righe. Con queste modifiche, le immagini del nodo appariranno sul controllo TreeView. Se disponi di un controllo ImageList con immagini caricate, modifica i numeri di indice in base all'immagine che desideri inserire nei nodi.
Il TreeView0_NodeClick() Event Procedure Espande il nodo corrente, se i nodi figlio sono in uno stato compresso, altrimenti i nodi figlio verranno compressi. Normalmente questa azione è controllata (senza codice) cliccando su +/- Simbolo sulla linea ad albero del nodo con nodi figlio.
Le subroutine cmdExpand_Click() e cmdCollapse_Click() Eventi Espande tutti i nodi e comprime tutti i nodi rispettivamente.
Quando il codice sopra viene eseguito, il display appare come l'immagine di visualizzazione modulo fornita di seguito:
-
Puoi salvare il frmDragDrop Modulo e aprilo in Visualizzazione normale. Se tutto è andato bene, vedrai la schermata sopra. Prova Espandi tutto e Comprimi tutto Pulsanti di comando e controlla se funzionano anche loro. In caso contrario, ricontrolla che le seguenti impostazioni siano corrette o meno:
-
i) Il nome del controllo TreeView è:TreeView0
-
ii) Visualizza la scheda delle proprietà di Exampand All Pulsante di comando e seleziona [Procedura evento] in Al clic Proprietà dell'evento.
-
iii) Assicurati che la stessa impostazione sia intatta per Comprimi tutto Pulsante di comando anche.
-
iv) Fare clic su un nodo, con nodi figlio, per vedere se si comprimono o si espandono a clic ripetuti.
-
v) Se il controllo ImageList è inserito nel modulo, il suo nome deve essere ImageList1 .
Procediamo con la seconda parte del Codice VBA che implementa gli eventi Drag-Drop.
Seconda metà del codice VBA.
-
Copia la seguente seconda parte del codice VBA, sul modulo modulo frmDragDrop, che implementa l'azione Drag-Drop, e incollalo sotto il codice esistente:
Private Sub TreeView0_OLEStartDrag(Data As Object, AllowedEffects As Long) Set Me.TreeView0.SelectedItem = Nothing End Sub Private Sub TreeView0_OLEDragOver(Data As Object, _ Effect As Long, _ Button As Integer, _ Shift As Integer, _ x As Single, _ y As Single, _ State As Integer) Dim SelectedNode As MSComctlLib.Node Dim nodOver As MSComctlLib.Node If tv.SelectedItem Is Nothing Then 'Select a node if one is not selected Set SelectedNode = tv.HitTest(x, y) If Not SelectedNode Is Nothing Then SelectedNode.Selected = True End If Else If tv.HitTest(x, y) Is Nothing Then 'do nothing Else 'Highlight the node the mouse is over Set nodOver = tv.HitTest(x, y) Set tv.DropHighlight = nodOver End If End If End Sub Private Sub TreeView0_OLEDragDrop(Data As Object, _ Effect As Long, _ Button As Integer, _ Shift As Integer, _ x As Single, _ y As Single) Dim sourceNode As MSComctlLib.Node Dim SourceParentNode As MSComctlLib.Node Dim targetNode As MSComctlLib.Node Dim tmpRootNode As MSComctlLib.Node Dim strtmpNodKey As String Dim ChildNode As MSComctlLib.Node Dim strSPKey As String Dim strTargetKey As String Dim strsQL As String Dim intKey As Integer Dim intPKey As Integer On Error Resume Next Select Case Screen.ActiveControl.Name Case TreeView0.Name Set sourceNode = tv.SelectedItem End Select 'Get Source Parent Node & Target Node Reference Set SourceParentNode = sourceNode.Parent Set targetNode = tv.HitTest(x, y) 'If any errors then exit If Err <> 0 Then MsgBox Err & " : " & Err.Description, vbInformation + vbCritical, "OLEDragDrop()" Err.Clear Exit Sub Else On Error GoTo 0 End If 'Get/define Source parent Node Key to compare it with Target Node Key If SourceParentNode Is Nothing Then strSPKey = "Empty" Else strSPKey = SourceParentNode.Key End If 'Check the Target Node/Location and define the Key Select Case True Case targetNode Is Nothing strTargetKey = "Empty" Case targetNode.Key = "" strTargetKey = "Empty" Set targetNode = Nothing Case Else strTargetKey = targetNode.Key End Select 'Make sure the Target Node is not the source Node's own parent If strTargetKey = strSPKey Then Exit Sub 'Track User's Node move action, check for error. On Error Resume Next If targetNode Is Nothing Then 'If target Node is Nothing (the Node dropped in the empty area), 'then the Node must be moved to the Root-level 'save the original sourceNode.Key strtmpNodKey = sourceNode.Key 'Modify the source Node Key, with addition of some text, say 'Empty', like 'X5Empty' 'So that a temporary Node can be created with the original source Node key. 'Note: Two Nodes with the same Key cannot remain in memory at the same time. 'The Source Node with key 'X5Empty' deleted later, 'temporary Node takes it's droped location. sourceNode.Key = sourceNode.Key & strTargetKey 'Create the temporary Root Node, with original sourceNode Key Set tmpRootNode = tv.Nodes.Add(, , strtmpNodKey, sourceNode.Text) 'define the Root Node image indexes 'With tmpRootNode ' .Image = 1 ' .SelectedImage = 4 'End With 'Move all child Nodes from SourceNode,if any, 'as tmpRootNode's Children Do Until sourceNode.Children = 0 Set sourceNode.Child.Parent = tmpRootNode 'modify Node image indexes 'With sourceNode ' .Image = 2 ' .SelectedImage = 3 'End With Loop 'Delete the Source Node with modified Key from TreeView tv.Nodes.Remove sourceNode.Index 'Move the tmpRootNode with original Key 'to the dropped location on TreeView Set sourceNode = tmpRootNode Else 'Move the sourceNode under targetNode as child Set sourceNode.Parent = targetNode 'modify Node image indexes 'With sourceNode ' .Image = 2 ' .SelectedImage = 3 'End With End If 'Notify, if there was an Error then Exit, else Update PrentID of related Record. If Err <> 0 Then MsgBox Err & " : " & "Unable to move:" & vbCrLf & Err.Description, vbInformation + vbCritical, "DragDrop2()" Exit Sub Else 'Build and execute the SQL statement to update the record If targetNode Is Nothing Then intKey = Val(Mid(sourceNode.Key, 2)) strsQL = "UPDATE Sample SET ParentID = Null" & _ " WHERE ID = " & intKey Else intKey = Val(Mid(sourceNode.Key, 2)) intPKey = Val(Mid(targetNode.Key, 2)) strsQL = "UPDATE sample SET ParentID = " & intPKey & _ " WHERE ID = " & intKey End If 'Modify the table records CurrentDb.Execute strsQL, dbFailOnError 'If an error raised then refresh TreeView and exit If Err <> 0 Then MsgBox Err & " : " & Err.Description LoadTreeView 'Refresh/display TreeView without changes Else 'Sort Nodes If sourceNode.Parent Is Nothing Then sourceNode.Root.Sorted = True Else sourceNode.Parent.Sorted = True End If tv.Nodes(sourceNode.Key).Selected = True End If End If On Error GoTo 0 End Sub Private Sub TreeView0_OLECompleteDrag(Effect As Long) 'Turn off the drophighlight Set tv.DropHighlight = Nothing End Sub Private Sub Form_Close() Set tv = Nothing End Sub
Per l'azione Drag-Drop, ci sono quattro subroutine, che vengono eseguite automaticamente quando trascini i nodi, evidenzia il nodo quando viene spostato su altri nodi e infine lo rilascia su un nodo diverso o sull'area vuota a livello di radice .
Le principali subroutine del codice.
- TreeView0_OLEStartDrag() - Inizializza l'elemento selezionato e imposta il Nodo su Niente
- TreeView0_OLEDragOver() - Funziona come l'evento di spostamento del mouse, evidenzia il nodo, quando trascina un nodo sopra di esso, sulla strada per il nodo di destinazione.
- TreeView0_OLEDragDrop() – Esegue controlli e controlli, posiziona i nodi nella posizione rilasciata e aggiorna il record sulla tabella di base.
- TreeView0_OLECompleteDrag() - La proprietà DropHighlight è impostata su Nothing.
Possiamo eseguire i lavori di trascinamento della selezione con TreeView0_OLEDragDrop() Solo sottoprogramma. In tal caso, non ci sarà alcuna evidenziazione del nodo, quando il nodo sorgente si sposta su altri nodi, da una posizione all'altra, tranne per il fatto che il puntatore del mouse cambia trascinando una seconda freccia dietro di esso, come nell'immagine di esempio riportata di seguito :
Quindi, presteremo attenzione a questa subroutine e verificheremo il codice in dettaglio dall'inizio. All'inizio della subroutine, abbiamo dichiarato i Nodi e le Variabili String necessari e altri.
Invece di ripetere le analisi riga per riga qui, ho commentato opportunamente ogni riga/sezione di codice in modo che tu possa capire cosa fa quando esamini il codice. Puoi esaminarli.
La sequenza degli eventi Drap Drop
Cerchiamo di capire la sequenza di Eventi, l'Utente Seleziona un nodo, trascina su altri nodi sulla strada per la destinazione finale e rilascia sul nodo di destinazione. Oppure rilascialo nell'area vuota del controllo TreeView, per renderlo un nodo a livello di radice.
Quando trascini un Nodo su un altro Node-Text, il Node-Text viene evidenziato, dicendo che la tua posizione attuale è su questo Nodo in arrivo, ovunque tu stia andando da qui. Quando viene spostato fuori dal testo del nodo, l'evidenziazione scompare. Questo accade fino al nodo di destinazione. Il TreeView0_OLEDragOver() Subroutine si occupa di questa azione di evidenziazione.
Quando rilasci un nodo da qualche parte, TreeView0_OLEDragDrop() La subroutine viene sovraccaricata. Qui, dobbiamo analizzare le intenzioni dell'Utente e intraprendere le azioni appropriate. Le seguenti informazioni devono essere salvate e analizzate per spostare il Nodo nella posizione corretta.
Le informazioni importanti di cui tenere traccia.
-
Il riferimento del nodo di origine, la chiave del nodo e i valori ParentID, i figli del nodo, se presenti.
-
Il nodo di destinazione o il riferimento della posizione, la chiave del nodo.
-
Se il Target non è un Nodo ma l'area vuota del Controllo TreeView, allora il Nodo Sorgente deve essere spostato nella posizione del livello principale.
-
Il nodo di origine quando viene rilasciato su un altro nodo, il nodo di destinazione diventa il nuovo genitore del nodo di origine.
-
Se Source Node ha i suoi figli, anche loro devono essere spostati con il loro genitore.
-
** Quando il nodo viene trascinato e rilasciato sul proprio nodo padre, ignora questa azione.
** Ad esempio, controlla l'immagine sopra. Se trasciniamo il Casella di testo Node e rilascialo nei Controlli del nodo principale o trascina i Controlli Node e rilascialo nel Modulo del nodo padre quindi quelle mosse verranno ignorate.
-
** Se a livello di radice Il nodo viene trascinato e rilasciato nell'area vuota, quindi non verrà eseguita alcuna azione perché è già un nodo a livello di radice.
Per tutte le mosse valide di Node, è necessario aggiornare il ParentID valore del campo del record correlato nel campione Tabella.
Rilascio del nodo nell'area vuota a livello di radice.
Nel caso dell'articolo numero 3 sopra, dobbiamo creare un Nodo a livello di Root, con lo stesso ID Number del Nodo Sorgente, che non è consentito. Il valore chiave duplicato non è consentito nella gerarchia TreeView. Questa è l'unica area del Codice, dove troverai un po' di confusione sulla procedura seguita lì.
La procedura è la seguente:
-
Modifica la chiave del nodo TreeView esistente con l'aggiunta di del testo aggiuntivo (ad esempio Chiave X5 cambia a X5Vuoto ), per evitare conflitti di chiavi, durante la creazione di un nodo temporaneo con la chiave originale.
-
Crea un temporaneo Nodo con la chiave originale:X5.
-
Sposta tutti i nodi figlio dal nodo di origine, se presente, come nodi figlio al nodo temporaneo.
-
Elimina il nodo sorgente TreeView con la chiave modificata:X5Empty dal controllo TreeView, ma il record relativo sulla tabella Campione non viene toccato.
-
Sposta il temporaneo Nodo con la chiave originale X5 con i suoi figli alla posizione a livello di radice del controllo TreeView.
-
Aggiorna il campo ParentID del record correlato con una stringa di lunghezza zero ("") per contrassegnarlo come nodo a livello di radice.
Esperimenti personali di trascinamento della selezione.
Puoi provare tu stesso alcuni esperimenti Drag and Drop e vedere come funziona. Selezionare un nodo, fare clic e tenere premuto il pulsante sinistro del mouse, trascinare il nodo e rilasciarlo su un altro nodo, oppure rilasciarlo in un'area vuota del controllo TreeView. Quando trascini il Nodo su un altro Node-Text viene evidenziato e quando sei fuori dal Node l'evidenziazione scompare. Il nodo trascinato apparirà nella nuova posizione in cui lo hai rilasciato. Puoi ripetere questo esperimento di trascinamento selezionando un singolo nodo o un nodo con figli.
Sulla base di questo movimento di nodi, il ParentID del record correlato il valore del campo verrà aggiornato con la Chiave valore (ID) del record relativo al nodo di destinazione.
Perché la procedura di popolamento dei nodi in due passaggi?
Ora torneremo a LoadTreeView() Subroutine, per dare una seconda occhiata al processo in due fasi che abbiamo adottato per popolare tutti i nodi nel controllo TreeView.
-
Tutti i record nel campione Le tabelle vengono inizialmente aggiunte come nodi a livello di radice, utilizzando il valore del campo ID come chiave di nodo.
-
Nel secondo passaggio dei record, se il valore del campo ParentID è vuoto, quel Nodo rimarrà come Nodo a livello di radice, senza modifiche.
-
Tutti gli altri record relativi ai nodi con ParentID Value vengono spostati correttamente sotto il relativo nodo padre.
Naturalmente, sorge la domanda, perché dobbiamo farlo in questo modo?
Faremo un semplice esperimento per chiarire la risposta senza spiegarla in troppe parole. Potresti aver già eseguito alcune esecuzioni di prova di trascinamento della selezione e riorganizzato i nodi, nel processo ha aggiornato i valori ParentID di quel record con la modifica. Quindi, dobbiamo ripristinare i valori del record al loro stato originale nel campione Table, prima di iniziare una nuova demo.
Abbiamo già creato una copia della nostra tabella Campione in precedenza, con il nome Sample_bk come backup. Elimina il campione Tabella ed esegui una copia da Sample_bk con il nome originale:Campione .
Aprire la tabella e visualizzare i record e i relativi valori del campo ParentID. L'immagine di esempio della tabella è riportata di seguito:
I valori del campo ID sono numeri automatici e sono tutti in ordine sequenziale e tutti i valori ID sono univoci. La seguente semplice regola regola l'aggiunta di un nodo figlio al controllo TreeView.
La regola del nodo figlio semplice: Il ID genitore campo Valore (Chiave principale ) in un record prevede che esista già un nodo padre nel controllo TreeView, con lo stesso valore di Node-Key (l'ID).
Controlla il terzo record dall'alto, nell'immagine della tabella sopra. Il valore del campo ParentID è 2 e l'ID del record corrente è 3. In questo caso, il record con ID 2 verrà aggiunto al controllo TreeView prima di tentare di aggiungere il terzo record al nodo. Entrambi i record non sono necessariamente uno accanto all'altro. Controlla il record con il numero ID 21, il suo valore del campo ParentID è 12, inferiore al valore ID del record corrente 21.
In entrambi i casi, quando il programma incontra il valore ParentID in un record, presuppone che il record con il valore ID uguale a ParentID sia stato già aggiunto come nodo nel controllo TreeView nel precedente ciclo di popolamento dei nodi.
Giustificare la procedura in due passaggi.
Proviamo alcune prove di Drag-Drop. Ma prima abbiamo un modulo con il nome frmSample, quale abbiamo usato nella prima Sessione del Tutorial, e in questo abbiamo caricato tutti i Nodi TreeView in una volta sola. Sì, finora abbiamo seguito lo stesso metodo e d'ora in poi abbiamo bisogno di alcuni cambiamenti. Ma prima apriamo il vecchio form e vediamo come appaiono i Nodi sul Form.
-
Apri il modulo frmSample per vedere come appare la visualizzazione TreeView, con i record della tabella di esempio, caricati utilizzando la vecchia regola.
-
Se hai finito di visualizzare i nodi TreeView, chiudi il modulo.
-
Ora apri il frmDragDrop Modulo. Ci stiamo preparando a trascinare e rilasciare un nodo.
-
Seleziona il Nodo con la Tabella Node-Text, Fai clic e tieni premuto il pulsante sinistro del mouse, trascinalo e rilascialo sul Nodo, con il Modulo Node-Text.
-
La Tabella Nodo con i suoi Campi immediati del nodo figlio e i suoi nodi figlio vengono spostati come nodi figlio sotto il Modulo Nodo.
-
Chiudi il modulo frmDragDrop e aprilo di nuovo. I nodi appariranno correttamente, dove li hai rilasciati, come nell'immagine riportata di seguito.
-
Ora chiudi il modulo frmDragDrop.
-
Apri il modulo frmSample per vedere come appare questa modifica su questo modulo. Verrai accolto con un messaggio di errore, Elemento non trovato con Numero errore:35601.
-
Seleziona il pulsante di comando Debug per andare alla riga del codice evidenziata, dove si è verificato l'errore.
-
Punta il mouse su nodKey Param del metodo Add(), mostra X3, punto il mouse su ParentKey parametro e mostra X7.
Osservando questi due valori di parametro, possiamo presumere di essere nel record con il valore ID 3 e di provare a designare questo nodo come nodo figlio, per un altro nodo non ancora popolato nel controllo TreeView, con valore ID 7.
-
Premi F5 Tasto per visualizzare di nuovo la stessa finestra di dialogo e fai clic su Fine Pulsante di comando per interrompere il programma e visualizzare il modulo nella finestra del database. Chiudi il modulo frmSample.
-
Apri il campione Tabella per visualizzare la disposizione dei numeri ParentID, dopo la nostra azione di trascinamento della selezione. I record avranno l'aspetto dell'immagine riportata di seguito e ho evidenziato il record che ha attivato l'errore con valore ParentID 7 e mostrando la posizione del record principale.
Seguendo la precedente procedura normale di popolamento del nodo, siamo alla terza posizione del record. Dal momento che, il valore ParentID dei record 7, il Nod con ID valore 7 deve essere presente nel controllo TreeView. Il nodo con valore ID 7 non è ancora popolato nel controllo TreeView, ma stiamo cercando di fare riferimento al nodo inesistente e questo provoca un errore.
Anche se ordini i record nel campo ParentID, la nuova disposizione dei record sarà simile all'immagine riportata di seguito:
Ora, il nodo padre di un altro record non è nella posizione prevista.
Quindi, in queste circostanze, il nostro approccio di caricamento dei nodi TreeView in due fasi funziona sia per le azioni normali che dopo il trascinamento della selezione.
Nel primo passaggio, popola tutti i record come nodi a livello radice nel controllo TreeView utilizzando il valore del campo ID come chiave di nodo.
Ora, tutti i nodi di tutti i record sono disponibili nel controllo TreeView. Sarà facile spostarli dove vogliamo. Non dice che nessuno dei nodi richiesti non esiste in TreeView.
Nel secondo passaggio sullo stesso set di record, i record con valori di campo ParentID vuoti non vengono toccati e possono rimanere come nodi a livello radice. In altri casi sposta il nodo come nodo figlio sotto il suo nodo padre, aggiornando il [Relativo] Parametro del Nodo con la seguente Istruzione:
Set tv.Nodes.Item(strKey).Parent = tv.Nodes.Item(strPKey)
This is what we do through the second pass on the same set of records. You may do it by resetting the Record Pointer to the first record, by executing rst.MoveFirst before the Do . . . Loop, EOF conditions and rst.MoveNext to access each record as we normally do.
Second Step in Reverse Order.
Or you may do it in reverse order. After populating all records as Root-level Nodes the Record Pointer will be beyond the last record and on the EOF posizione. You may reset the record pointer to the last record, by executing rst.MoveLast before the Do . . . Loop BOF check, and execute rst.MovePrevious to access each record and move the Nodes correctly under its p arent Node. But, the Nodes may load slightly differently in the placement order of Nodes.
You may try this out yourself with the above-suggested change of Code and see the result.
Download Demo Database
- Modulo di classe MS-Access e VBA
- Matrici di oggetti di classe VBA MS-Access
- Classe base MS-Access e oggetti derivati
- Classe base VBA e oggetto derivato-2
- Classe base e varianti di oggetti derivati
- Recordset MS-Access e modulo di classe
- Accedi al modulo di classe e alle classi wrapper
- Trasformazione della funzionalità della classe wrapper