TreeView и база данных
TreeView и база данных
TreeView и база данных framez Есть таблица вида id | name | idpar, где idpar - id родителя в этой же таблице. В treeview отображается дерево этой таблицы. Дерево загружается не все, а по частям (т.е. ветвь загружается при нажатии на +) Необходимо при добавлении новой записи обновить дерево и выделить ту запись, которая была выделена до внесения изменений. После добавления записи я сворачиваю дерево и все... Я не могу выделить ту запись на которой был до изменения. я пробую развернуть 1 ветку, а получается что разворачивается все дерево... второй день не могу понять в чем дело Я по разному пробовал но не получается он разворачивает все дерево а мне этого не надо. procedure tmainform.n10click(sender: tobject); begin // добавление подразделения with tgroupeditform.create(self, 0, 0, true) do try showmodal; finally free; end; shownode(grouptview.selected); end; procedure tmainform.shownode(node : ttreenode); var list : tstringlist; i : integer; begin list := tstringlist.create; while node.parent <> nil do begin list.add(node.text); node := node.parent; end; grouptview.fullcollapse; grouptview.items.item[0].expand(true); for i := list.count-1 downto 1 do begin while node.getnextchild(node) <> nil do if node.text = list.strings[i] then node.expand(true); end; list.free; end; -------------------------------------------------------------------------------- а зачем после добавления записи обновлять все дерево? если так уж хочется обновлять, то непонятно что за проблемы развернуть ветку, не надо рекурсивно открывать её. я пару дней назад переписывал работу с деревом - решил не заморачиваться на считывание данных по мере надобности и вычитываю сразу все и набору строю дерево. Записей около 2 тыс, строится за секунду. type tnodevalue = class public name: string; node: ttreenode; id: extended; orgid: extended; bsotype: extended; parentid: extended; placeid: extended; constructor create(ds: tdataset);overload; constructor create(pid, porgid, pbsotype, pparentid, pplaceid: extended; pname:string);overload; procedure assigndata(pid, porgid, pbsotype, pparentid, pplaceid: extended; pname:string); end; .... procedure ttempl.rebuildtree; var root: ttreenode; nv: tnodevalue; begin tv.items.beginupdate(); try tv.items.clear(); fnodesmanager.clear(); cds.emptydataset(); fillcds(querytemplatetree); cds.first(); if cds.recordcount>0 then begin nv := tnodevalue.create(cds); root := tv.items.addchildobject(nil, nv.name, nv); nv.node := root; fnodesmanager.add(nv); fillchildren(cds, root, tv.items, cds.fieldbyname('templateid').asfloat); end; if tv.items.getfirstnode() <> nil then begin tv.items.getfirstnode.expand(false); tv.items.getfirstnode.selected := true; end; finally tv.items.endupdate; end; end; procedure ttempl.fillchildren(ds: tclientdataset; root: ttreenode; nodes: ttreenodes; parentid: extended); var nd: ttreenode; i: integer; lst: tlist; nv: tnodevalue; pos: integer; begin cds.setrange([parentid], [parentid]); lst := tlist.create(); try while not cds.eof do begin nv := tnodevalue.create(cds); nd := nodes.addchildobject(root, nv.name, nv); nv.node := nd; lst.add( pointer(fnodesmanager.add(nv)) ); cds.next(); end; cds.cancelrange(); for i:=0 to lst.count-1 do begin pos := integer(lst[i]); nv := fnodesmanager.items[ pos ]; fillchildren(cds, nv.node, nodes, nv.id); end; finally lst.free(); end; end; ... procedure ttempl.tvchange(sender: tobject; node: ttreenode); var nv: tnodevalue; begin pmtemplatetreepopup( pmtemplatetree); if node = nil then exit; nv := tnodevalue(node.data); setsubdsparams(nv); end; cds это tclientdataset, в нем должен существовать и быть активным индекс по parentid Источник: http://www.delphimaster.ru/