Въведение.
Надявам се, че сте намерили урока от миналата седмица за ImageCombo Control полезен за вашите проекти на Microsoft Access. С TreeView ImageCombo Control бихме могли да създадем красиво падащо меню с няколко опции и да го поставим в малко пространство във формуляра.
По същия начин, в по-ранна сесия, научихме как да добавяме нови възли на определено място в йерархията на възлите или да изтриваме възел и да добавяме нов, за да преместим възел в контролата на дървовидния изглед.
Този метод изисква създаването на нов запис в изходната таблица за новия възел. Или изтрийте съществуващ запис и създайте нов, за да преместите съществуващ възел, за да го направите постоянен. По някакъв начин, с използването на функции за добавяне/изтриване, бихме могли да добавим нови възли или да пренаредим съществуващите възли в контролата TreeView. Що се отнася до пренареждането на възли, имаме по-добър начин да го направим, вместо да изтриваме възли и да ги създаваме отново. Плъзнете възела от текущото му местоположение и го пуснете там, където искаме да бъде в TreeView Control. Това ще научим в този епизод
Този прост подход се нуждае само от актуализиране на промяната на стойността на полето ParentID на свързани записи, за да направи промяната постоянна.
Темите, разгледани досега в по-ранните сесии.
- Урок за контрол на Microsoft TreeView
- Създаване на меню за достъп с TreeView Control
- Присвояване на изображения към TreeView Control
- Присвояване на изображения към TreeView Control-2
- TreeView Control Маркирайте отметка за добавяне на изтриване на възли
- Падащо меню за достъп до TreeView ImageCombo
Но може да се сблъскаме с някои предизвикателства, докато използваме този метод и ще стигнем до това малко по-късно в тази сесия.
Таблица и формуляр с демонстрационни данни.
Нуждаем се от таблица и формуляр. Вече имаме подходяща таблица с имеПроба създадена в по-ранна сесия с урок. Ако вече сте изтеглили Демо базата данни от втората страница с връзка, дадена по-горе, тогава можете да използвате тази база данни и за тази сесия. Ще използваме следните обекти от тази база данни за нашите експерименти с плъзгане:
- Таблица:Проба
- Формуляр:frmSample
Контролното изображение на TreeView на frmSample с демонстрационни данни е дадено по-долу за справка:
Можете да изтеглите Демо базата данни (ProjectMenu.zip ) от втората страница с връзка, дадена по-горе, и извлечете ProjectMenu.accdb база данни.
Нов формуляр за пробни стартирания с плъзгане.
-
Отворете базата данни ProjectMenu.accdb.
-
Направете копие на таблицата Проба и го наименувайте като Sample_bk, пазете го, ще ни трябват оригиналните му данни без промяна по-късно. Когато експериментираме с метода на плъзгане и пускане, е необходимо да актуализираме стойността на полето ParentId в Примерната демонстрационна таблица. Но оригиналните данни ни трябват по-късно, без тези промени.
-
Създайте нов формуляр с името frmDragDrop .
-
Дизайнът на формуляр frmDragDrop ще изглежда като изображението, дадено по-долу, когато приключите с него.
-
Поставете контролата TreeView от списъка с ActiveX контроли и я поставете във формуляра, оставяйки достатъчно място над контролата, така че да можем да създадем два командни бутона и етикет за заглавие над нея. Плъзнете манипулатора за оразмеряване в долния десен ъгъл, за да го направите достатъчно голям за показване на всички възли, без да превъртате.
-
Променете Име Стойност на свойството на TreeView Control към TreeView0 .
-
Поставете команден бутон над и левия ръб на TreeView Control. Променете неговото Име Стойност на свойството до cmdExpand и Надпис стойност на Разгъване на всички .
- Вмъкнете втори команден бутон над и в десния край на TreeView Control. Променете неговото Име Стойност на свойството до cmdCollapse и Надпис Стойност на свойството за Свиване на всички
-
Поставете контрола за етикет над командните бутони, достатъчно широка, за да напишете заглавието, както е показано по-горе, и променете неговия размер на шрифта 14.
-
Игнорирайте контролата ImageList, за момента коментирах кодовите линии, които променят индексните номера на Node ImageList. По-късно можете да импортирате контрола ImageList с ръчно качени изображения от нашата по-ранна демонстрационна база данни (от 4-та страница с връзки, дадена по-горе) и да го използвате за показване на изображения на възли на възли. Когато позициите на възела се променят по време на действията Drag Drop, ние трябва да променим изображенията на възела също в зависимост от позицията на възела (възел на коренно ниво или възел на дете) в контролата TreeView.
Код на модула на формуляра с плъзгане.
-
Покажете кодовия модул на VBA на формуляра frmDragDrop, копирайте и поставете следния VBA код (това е само първата половина от кода на модула на формуляра) в модула за клас на frmDragDrop Form и запазете формуляра:
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
Знам, че сте запознати с горния код, ако вече сте преминали през по-ранните епизоди, с изключение на LoadTreeView() подпрограма с някои промени. Тук попълването на TreeView възлите е разделено на процес от две стъпки.
Накратко, това се случва в тази подпрограма.
Всички записи в Проба Таблицата е заредена като възли на коренно ниво на TreeView Control, със стойност на полето ID като ключ, в първата стъпка.
Отново, тези записи бяха прочетени за втори път и проверете за стойност в ParentId поле, ако е празно, тогава възелът ще бъде запазен като възел на коренно ниво.
Ако полето ParentID има Стойност, тогава идентифицирайте възела със стойността ParentID като Node-Key и преместете текущия възел като негов дъщерен възел или неговия [относителен] Параметър (от Добавяне () Метод) стойността се актуализира.
-
Въпреки че изглежда, че двуетапната процедура за попълване на възли е ненужно упражнение, има добра причина да следваме този метод. Ще се върнем към това малко по-късно и ще го разберете без много обяснения.
-
На дизайна на формуляра съм дал контрола ImageList. Можете да вмъкнете ImageList ActiveX Control и качете някои изображения в него ръчно от диска или копирайте и поставете тази контрола с изображения от по-ранни изтегляния на демонстрационна база данни. И в двата случая, моля, уверете се, че името на контролата ImageList е ImageList1 . В противен случай трябва да промените името в кода.
-
След това активирайте коментираните редове в процедурата за събитие Form_Open(). Активирайте следните редове, като премахнете символа за коментар от началото на реда:
'Set imgListObj = Me.ImageList1.Object 'tv.ImageList = imgListObj
-
В TreeView0_ OLEDragDrop() Подпрограмата (във 2-ра част на VBA кода) позволява параметрите на индекса на изображението на възлите, като премахва и символите за коментар от тези редове. С тези промени изображенията на възел ще се появят в контролата TreeView. Ако имате своя собствена контрола ImageList с качени изображения, тогава променете индексните номера въз основа на това какво изображение искате да вмъкнете във възлите.
TreeView0_NodeClick() Процедура за събитие Разширява текущия възел, ако дъщерните възли са в свито състояние, в противен случай дъщерните възли ще бъдат свити. Обикновено това действие се контролира (без код) чрез щракване върху +/- Символ на дървовидната линия на възела с дъщерни възли.
Подпрограмите cmdExpand_Click() и cmdCollapse_Click() Събития Разгъва всички възли и съответно свива всички възли.
Когато горният код се изпълнява, дисплеят изглежда като изображението за изглед на формуляр, дадено по-долу:
-
Можете да запазите frmDragDrop Формуляр и го отворете в нормален изглед. Ако всичко е минало добре, ще видите горния екран. Изпробвайте Разгъване на всички и Свиване на всички Командни бутони и проверете дали и те работят. Ако не, проверете отново дали следните настройки са правилни или не:
-
i) Името на TreeView Control е:TreeView0
-
ii) Показване на листа със свойства на Exampand All Команден бутон и изберете [Процедура за събитие] в При щракване Свойство на събитието.
-
iii) Уверете се, че същата настройка е непокътната за Сгъване на всички Команден бутон също.
-
iv) Щракнете върху възел, който има дъщерни възли, за да видите дали те се свиват или разширяват при многократно щракване.
-
v) Ако контролата ImageList е поставена във формуляра, тогава името му трябва да бъде ImageList1 .
Нека продължим с втората част от VBA кода, която имплементира събитията с плъзгане и пускане.
Втората половина на VBA кода.
-
Копирайте следната втора част от VBA кода в модула frmDragDrop, който изпълнява действието Drag-Drop, и го поставете под съществуващия код:
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
За действието Drag-Drop има четири подпрограми, те са се изпълнили автоматично, когато плъзнете възела(ите), подчертава възела, когато се премести върху други възли и накрая го пуска на различен възел или в празната зона на коренно ниво .
Основните подпрограми на кода.
- TreeView0_OLEStartDrag() - Инициализира избрания елемент и задава възела на нищо
- TreeView0_OLEDragOver() - Работи като събитието Mouse Move, подчертава възела, когато плъзга възел над него, по пътя към целевия възел.
- TreeView0_OLEDragDrop() – Извършва проверка и контрол, позиционира възела(ите) в изпуснатото местоположение и актуализира записа в основната таблица.
- TreeView0_OLECompleteDrag() - Свойството DropHighlight е настроено на нищо.
Можем да направим Drag and Drop работи с TreeView0_OLEDragDrop() Само подпрограма. В този случай няма да има открояване на възел, когато изходният възел се движи над други възли, от едно място на друго, освен че показалецът на мишката се променя на плъзгане на втора стрелка зад него, както в примерното изображение, дадено по-долу :
Така че ще обърнем внимание на тази подпрограма и ще проверим подробно кода от самото начало. В началото на подпрограмата сме декларирали необходимите възли и низови променливи и други.
Вместо да повтарям анализите ред по ред тук, коментирах всеки ред/раздел от кодове по подходящ начин, така че да разберете какво прави, когато преминете през Кодекса. Можете да преминете през тях.
Последователността на събитията Drap Drop
Нека разберем последователността на събитията, които потребителят избира възел, плъзга се над други възли по пътя към крайната му дестинация и изпуска го на целевия възел. Или го пуснете върху празната област на TreeView Control, за да го направите възел на коренно ниво.
Когато плъзнете възел върху друг текст на възел, текстът на възел се маркира, казвайки, че текущата ви позиция е на този възел по пътя, където и да отидете оттук. Когато се измести от текста на възела, подчертаването изчезва. Това се случва до целевия възел. TreeView0_OLEDragOver() Подпрограмата се грижи за това действие за подчертаване.
Когато пуснете възел някъде, TreeView0_OLEDragDrop() Подпрограмата поема свръхзареждане. Тук трябва да анализираме намеренията на потребителя и да предприемем съответните действия. Следната информация трябва да бъде запазена и анализирана, за да преместите възела на правилното място.
Важната информация, която трябва да следите.
-
Препратката към изходния възел, стойностите на ключ на възел и родителски идентификатор, деца на възел, ако има такива.
-
Справочник за целевия възел или местоположение, ключ на възел.
-
Ако целта не е възел, а празната област на контролата TreeView, тогава възелът източник трябва да бъде преместен в позиция на основно ниво.
-
Възелът източник, когато бъде пуснат на друг възел, целевият възел става новият родител на изходния възел.
-
Ако изходният възел има свои собствени деца, те също трябва да бъдат преместени със своя родител.
-
** Когато възелът се плъзне и пусне върху неговия собствен родителски възел, тогава игнорирайте това действие.
** Например, проверете изображението по-горе. Ако плъзнем TextBox Възел и го пуснете в неговия родителски възел Контроли, или плъзга Контролите Node и го пуснете на неговия родителски възел Формуляр тогава тези ходове ще бъдат игнорирани.
-
** Ако Root-ниво Възелът се плъзга и пуска в празната област, след което няма да се предприемат никакви действия, защото вече е възел на коренно ниво.
За всички валидни движения на Node трябва да актуализираме ParentID стойност на полето на свързания запис в Проба Таблица.
Изпускане на възел в празната област на коренно ниво.
В случай на артикул номер3 по-горе, трябва да създадем възел на коренно ниво, със същия идентификационен номер на изходния възел, което не е разрешено. Дублирана стойност на ключ не е разрешена в йерархията на TreeView. Това е единствената част от Кодекса, където ще откриете малко объркване относно процедурата, следвана там.
Процедурата е както следва:
-
Променете съществуващия ключ на възел TreeView с добавяне на допълнителен текст (кажете ключ X5 промяна до X5Empty ), за да избегнете конфликти на ключове, докато създавате временен възел с оригиналния ключ.
-
Създайте временен Възел с оригиналния ключ:X5.
-
Преместете всички дъщерни възли от изходния възел, ако има такива, като дъщерни възли към временния възел.
-
Изтрийте изходния възел на TreeView с модифицирания ключ:X5Empty от TreeView Control, но свързаният запис в таблицата с примери не е докоснат.
-
Преместете временните Възел с оригиналния ключ X5 с неговите деца до позицията на коренно ниво на контролата TreeView.
-
Актуализирайте полето ParentID на свързания запис с низ с нулева дължина (“”), за да го маркирате като възел на коренно ниво.
Самоексперименти на Drag Drop.
Можете сами да изпробвате някои експерименти с плъзгане и пускане и да видите как работи. Изберете възел, щракнете и задръжте левия бутон на мишката, плъзнете възела и го пуснете върху друг възел или го пуснете в празна област на контролата TreeView. Когато плъзнете възела върху друг възел-текст, той се маркира и когато сте извън възела, акцентът изгасва. Влаченият възел ще се появи на новото място, където сте го пуснали. Можете да повторите този експеримент с плъзгане и пускане, като изберете един възел или възел с деца.
Въз основа на това движение на възлите ParentID на свързания запис стойността на полето ще бъде актуализирана с Ключ стойност (ID) на записа, свързан с целевия възел.
Защо процедура за попълване на възел в две стъпки?
Сега ще се върнем към LoadTreeView() Подпрограма, за да разгледаме отново процеса в две стъпки, който сме приели за попълване на всички възли в TreeView Control.
-
Всички записи в Извадката Първоначално таблицата се добавя като възли на коренно ниво, като се използва стойността на полето ID като възел-ключ.
-
При второто преминаване на записите, ако стойността на полето ParentID е празна, тогава този възел ще остане като възел на коренно ниво, без промяна.
-
Всички други записи, свързани с възли със стойност на ParentID, са правилно преместени под родителския възел.
Естествено възниква въпросът защо трябва да го правим по този начин?
Ще направим прост експеримент, за да направим отговора ясен, без да го обясняваме с твърде много думи. Може би вече сте направили някои пробни пуска на пробни пускания с плъзгане и пускане сами и сте пренаредили възли, като в процеса актуализирате стойностите на ParentID на тези записи с промяната. Така че трябва да нулираме стойностите на записа до първоначалното им състояние в Проба Таблица, преди да започнем нова демонстрация.
Вече създадохме копие на нашата таблица Проба по-рано, с името Sample_bk като резерв. Изтрийте Пробата Таблица и направете копие от Sample_bk с оригиналното име:Проба .
Отворете таблицата и вижте записите и техните стойности на полето ParentID. Примерното изображение на таблицата е дадено по-долу:
Стойностите на полето за идентификатор са автоматични номера и всички те са в последователен ред и всички стойности на идентификатор са уникални. Следното просто правило управлява добавянето на дъщерен възел към контролата TreeView.
Правило за прост дъщерен възел: ParentID Стойност на полето (Родителски ключ ) в запис очаква, че родителски възел вече съществува в TreeView Control, със същата стойност като Node-Key (идентификацията).
Проверете третия запис отгоре, в горното изображение на таблицата. Стойността на полето ParentID е 2, а ID на текущия запис е 3. В този случай записът с ID 2 ще бъде добавен към TreeView Control, преди да се опитаме да добавим третия запис към възела. И двата записа не са непременно един до друг. Проверете записа с идентификационен номер 21, стойността на полето на ParentID е 12, по-малко от текущата стойност на ID на записите 21.
И в двата случая, когато програмата срещне стойността на ParentID в запис, тя приема, че записът със стойност на ID, равна на ParentID, вече е добавен като възел в TreeView Control в по-ранния цикъл на попълване на възлите.
Обосноваване на процедурата в две стъпки.
Нека опитаме някои пробни пускания с плъзгане. Но преди това имаме формуляр с името frmSample, коя използвахме в първата учебна сесия и в нея заредихме всички възли на TreeView наведнъж. Да, досега сме следвали същия метод и отсега нататък се нуждаем от промяна. Но преди това нека отворим стария формуляр и да видим как възлите се появяват във формуляра.
-
Отворете формуляра frmSample за да видите как изглежда екранът на TreeView със записите на Примерна таблица, заредени с помощта на старото правило.
-
Ако преглеждате възлите на TreeView, затворете формуляра.
-
Сега отворете frmDragDrop Формуляр. Подготвяме се да плъзгаме и пускаме възел.
-
Изберете възела с Таблицата с текст на възел, Щракнете и задръжте левия бутон на мишката, плъзнете го и го пуснете върху възела с формуляра за текст на възел.
-
Таблицата Възел с неговите непосредствени Полета на дъщерния възел и неговите дъщерни възли се преместват като дъщерни възли под Формуляр Възел.
-
Затворете формуляра frmDragDrop и го отворете отново. Възлите ще се появят правилно там, където сте ги пуснали, като изображението по-долу.
-
Сега затворете формуляра frmDragDrop.
-
Отворете формуляра frmSample за да видите как се появява тази промяна в този формуляр. Ще бъдете посрещнати със съобщение за грешка Елементът не е намерен сНомер на грешка:35601.
-
Изберете командния бутон за отстраняване на грешки, за да отидете на маркирания ред на кода, където е възникнала грешка.
-
Насочете мишката върху nodKey Параметър на метода Add(), той показва X3, точка мишката върху ParentKey параметър и той показва X7.
Разглеждайки тези две стойности на параметъра, можем да предположим, че сме в записа със стойност на идентификатора 3 и се опитваме да обозначим този възел като дъщерен възел, към друг възел, който все още не е попълнен в контролата TreeView, със стойност на ID 7.
-
Натиснете F5 Натиснете, за да изведете отново същия диалогов прозорец и щракнете върху Край Команден бутон за спиране на програмата и извеждане на формуляра в прозореца на базата данни. Затворете frmSample Form.
-
Отворете Проба Таблица, за да видите подредбата на номерата на ParentID, след нашето действие с плъзгане и пускане. Записите ще изглеждат като изображението, дадено по-долу и маркирах записа, който е задействал грешката със стойност на ParentID 7 и показва позицията на неговия родителски запис.
Следвайки нормалната процедура за попълване на възел по-рано, ние сме на третата позиция за запис. Тъй като записва стойност на ParentID 7, Nod със стойност на ID 7 трябва да присъства в TreeView Control. Възелът със стойност на ID 7 все още не е попълнено в TreeView Control, но се опитваме да препратим към несъществуващия възел и това задейства грешка.
Дори ако сортирате записите в реда на полето ParentID, новото подреждане на записите ще изглежда като изображението, дадено по-долу:
Сега родителският възел на друг запис не е в очакваната позиция.
Следователно, при тези обстоятелства, нашият двуетапен подход за зареждане на TreeView Nodes работи както за нормални, така и за действия след плъзгане и пускане.
В първата стъпка попълнете всички записи като възли на коренно ниво в TreeView Control, като използвате стойността на полето ID като възел-ключ.
Сега всички възли на всички записи са налични в TreeView Control. Ще бъде лесно да ги преместим, където пожелаем. Не се казва, че някой от необходимия възел не съществува в TreeView.
In the second pass on the same set of records, the records with empty ParentID field values are untouched and allowed to remain as Root-level Nodes. In other cases moves the Node as Child-Node under its Parent Node, by updating the [Relative] Parameter of the Node with the following Statement:
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 position. 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
- Модул за MS-Access Class и VBA
- Обектни масиви от клас VBA на MS-Access
- Основен клас на MS-Access и производни обекти
- VBA Base Class and Derived Object-2
- Варианти на основен клас и производен обект
- MS-Access Recordset and Class Module
- Достъп до модул за класове и класове за обвивка
- Преобразуване на функционалност на класа на обвивката