Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > проблема при добавлении ноды в VirtualStringTree


Автор: bistropoke 26.10.2011, 20:03
подскажите в чем может быть ошибка?
заполняю VST данными из базы

в самом начале я заполняю VST нодами нулевого уровня.

Код

squery:='select idtype_params as id,name from type_params where level =0';
     form1.SQLQuery1.SQL.Clear;
     form1.SQLQuery1.SQL.Text :=  squery;
     form1.SQLQuery1.Open;
     while not form1.SQLQuery1.EOF do begin
       nodename:= form1.SQLQuery1.FieldByName('name').AsString;
       nodeid:=form1.SQLQuery1.FieldByName('id').AsInteger;
       nodelevel:= 0  ;
       XNode:=form1.VT.AddChild(nil);
       if form1.VT.AbsoluteIndex(xnode)>-1 then
        begin
          data:= form1.vt.GetNodeData(xnode);
          data^.name:=nodename;
          data^.id:=nodeid;
          data^.level:=0;
          data^.parent:=-1;
        end;
     form1.SQLQuery1.Next;
     end;
     form1.SQLQuery1.Close;     


далее хочу добавить ноды второго уровня

Код

query:='select tp.idtype_params as id,tp.name,tp.parent, tp.sname, nei.name as edizm from type_params as tp join nsi_edizm as nei on tp.ediz_m=nei.idnsi_edizm where tp.level = '+inttostr(y);
     form1.SQLQuery1.SQL.Clear;
     form1.SQLQuery1.SQL.Text :=  squery;
     form1.SQLQuery1.Open;
      while not form1.SQLQuery1.EOF do begin
       nodename:= form1.SQLQuery1.FieldByName('name').AsString;
       nodeid:=form1.SQLQuery1.FieldByName('id').AsInteger;
       nodelevel:= y;
       nodeparent:= form1.SQLQuery1.FieldByName('parent').AsInteger;
       nodeedizm:= form1.SQLQuery1.FieldByName('edizm').Asstring;
       nodesname:= form1.SQLQuery1.FieldByName('sname').AsString;
      // находим родителя
       XNode:= form1.VT.GetFirst;
        while XNode <> nil do
          begin
              Data:=form1.VT.GetNodeData(XNode);
              if Data^.id  = nodeparent then
                  begin
                        form1.VT.ClearSelection;
                        form1.VT.Selected[XNode]:=True;
                        form1.VT.SetFocus;
                        break;
                  end else
           XNode:= form1.VT.GetNextSibling(XNode);
        end;
       // добавляем ноду
          XNode := form1.VT.AddChild(form1.VT.FocusedNode);
          data:= form1.vt.GetNodeData(xnode);
          data^.name:=nodename;
          data^.id:=nodeid;
          data^.level:=y;
          data^.parent:=nodeparent;
          data^.edizm:=nodeedizm;
          data^.sname:=nodesname;
     form1.SQLQuery1.Next;
     end;
     form1.SQLQuery1.Close;         


но нода добавляется в корень.

при этом поиск ноды по условию parent потомка = id родителя успешен.
и нода выделяется.
но добавление происходит не как потомок у выделеной ноды
а как новая корневая нода.  smile 

Автор: MetalFan 26.10.2011, 21:41
Цитата(bistropoke @  26.10.2011,  20:03 Найти цитируемый пост)
if form1.VT.AbsoluteIndex(xnode)>-1 then

А что делает эта проверка?

И зачем такой изврат с визуальной частью? в плане сброса/установки выделения, передачи фокуса дереву, затем добавление ребенка FocusedNode, который скорее всего так и остался nil.

Автор: bistropoke 26.10.2011, 22:03
[QUOTE=MetalFan,26.10.2011,  21:41]
Цитата(bistropoke @  26.10.2011,  20:03 Найти цитируемый пост)
if  в плане сброса/установки выделения, передачи фокуса дереву, затем добавление ребенка FocusedNode, который скорее всего так и остался nil.

пожалуйста подскажите как сделать правильнее  smile 

Автор: MetalFan 26.10.2011, 22:43
выкинуть
Код

form1.VT.ClearSelection;
form1.VT.Selected[XNode]:=True;
form1.VT.SetFocus;

заменить
Код

// добавляем ноду
   XNode := form1.VT.AddChild(XNode);

Автор: bistropoke 26.10.2011, 23:36
спасибо 
переделал заполнение чайлдов в вид
Код

  // находим родителя
       XNode:= form1.VT.GetFirst;
        while XNode <> nil do
          begin
              Data:=form1.VT.GetNodeData(XNode);
              if Data^.id  = nodeparent then
                  begin
                   // добавляем ноду
                    XNode := form1.VT.AddChild(xnode);
                     data:= form1.vt.GetNodeData(xnode);
                     data^.name:=nodename;
                     data^.id:=nodeid;
                     data^.level:=y;
                     data^.parent:=nodeparent;
                     data^.edizm:=nodeedizm;
                     data^.sname:=nodesname;
                        break;
                  end else
           XNode:= form1.VT.GetNextSibling(XNode);
        end;
                            


сейчас работает хорошо.

возник сразу второй вопрос.
уже алгоритмический.
каким способом лучше заполнять VST из базы?
1. по уровням как делаю я ?
2. рекурсивно через запросы по полю parent ?

в первом случае минимизируются запросы к базе, но для каждой ноды выполняется проход по всему дереву в поиске ее родителя
во втором больше запросов к базе но дерево строиться без дополнительных проходов.

Автор: MetalFan 27.10.2011, 09:35
Цитата(bistropoke @  26.10.2011,  23:36 Найти цитируемый пост)
в первом случае минимизируются запросы к базе


хм, ну базы для того и были сделаны, чтобы хранить данные и быстро выполнять по ним запросы...


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)