Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.05;
Скачать: CL | DM;

Вниз

TreeView   Найти похожие ветки 

 
ДяволСД   (2006-10-18 08:18) [0]

Мне из базы нужно заполнить TreeView сделающим образом
Корень
 Категория 1
   Подкатегория 1
     подподкатегория 1
   Подкатегория 2
 Категория 2
И т.д....
Желательно ещё у ентих пунктов как-то хранить ID категории из базы. Данные в базе следующего вида: catid (ID категории), parentid (ID родителя категории 0 - родитель корень), name (Имя категории), ...
Как сие оптимально реализовать? Пасибо заранее за ответ!


 
Сергей М. ©   (2006-10-18 08:53) [1]


> Мне из базы нужно заполнить TreeView


DBTreeView чем не угодил ?


 
ДьяволСД   (2006-10-18 09:00) [2]

У меня база не через гриды таблицы и т.д. проходит. Я с базой работаю через юнит (мне так проще) соответственно привязать к DBTreeView не смогу


 
ДьяволСД   (2006-10-18 09:08) [3]

Хотяб подскажите как ID дополнительно хранить?


 
Сергей М. ©   (2006-10-18 09:15) [4]


> ДьяволСД   (18.10.06 09:00) [2]


Абракадабра какая-то ...


> как ID дополнительно хранить?
>


Например, в св-ве TTreeNode.Data


 
ДьяволСД   (2006-10-18 09:22) [5]

вообщем так я получаю данные
ResRow:=DB.exec("SELECT * FROM mag_categories ORDER BY `name` ASC");
while not ResRow.eof do
 begin
  cols:=ResRow.fieldcount;
  v:=ResRow[4]; // 1 - Catid, 3 - parentid, 4 - name
  a1:=VarToStr(v);
  CatsView.Items.AddChildFirst(nil,a1); // сделал тестовое заполнение корня
  ResRow.next
 end


 
ДьяволСД   (2006-10-18 09:27) [6]

Сергей М.
А не подскажите как интегер в поинте сохранить ентом? Где-то проскакивало, найти не могу :(


 
Сергей М. ©   (2006-10-18 09:49) [7]


> как интегер в поинте сохранить ентом?


SomeTreeNode.Data := Pointer(12345);


 
ДьяволСД   (2006-10-18 10:55) [8]

Я всё-таки енто сделал :) Если кому интересно, вот код:
procedure TMainForm.CatListFill(Tree: TTreeView);
var
 Nod:TTreeNode;

 Function FindTreeNode(FirstNode: TTreeNode; Const Pointid: integer): TTreeNode;
  Begin
   Result:= FirstNode;
   While Result <> Nil Do
     Begin
       If Integer(Result.Data) = Pointid Then Exit;
       Result:= Result.GetNext;
     End;
  End;

begin
ResRow:=DB.exec("SELECT * FROM mag_categories WHERE cattype <> "+onequote+
  "Deleted"+onequote+" ORDER BY `name` ASC");
Tree.Items.BeginUpdate;
Tree.SortType:=TSorttype(stNone);
while not ResRow.eof do
 begin
  if StrToInt(VarToStr(ResRow[3])) = 0 then
   begin
    TTreeNode(Tree.Items.Add(nil,VarToStr(ResRow[4]))).Data :=
     Pointer(StrToInt(VarToStr(ResRow[0]))); //Корневые ноды
   end
  else if StrToInt(VarToStr(ResRow[3])) <> 0 then
   begin
    Nod := FindTreeNode(CatsView.TopItem,StrToInt(VarToStr(ResRow[3])));
    TTreeNode(Tree.Items.AddChild(Nod,VarToStr(ResRow[4]))).Data :=
     Pointer(StrToInt(VarToStr(ResRow[0]))); // Добавляет под....
   end;
  ResRow.next
 end;
Tree.Items.EndUpdate;
end;

Всем спасибо :)))


 
Сергей М. ©   (2006-10-18 11:08) [9]

Боюсь что твой алгоритм когда-нибудь затрещит по швам.

Вот смотри :

  else if StrToInt(VarToStr(ResRow[3])) <> 0 then
  //узел не корневой
  begin
   //ищем родителя
   Nod := FindTreeNode(CatsView.TopItem,StrToInt(VarToStr(ResRow[3])));
   //если родитель не найден, то родителем создаваемого узла у тебя станет черт-те какой узел, но только не тот который должен быть
   TTreeNode(Tree.Items.AddChild(Nod,VarToStr(ResRow[4]))).Data :=
    Pointer(StrToInt(VarToStr(ResRow[0]))); // Добавляет под....
  end;

Нужен рекурсивный алгоритм, и одним SQL-запросом в общем случае не обойтись: для каждого "родителя" должен осуществляться SQL-запрос его "детей". Самый первый запрос должен вернуть корневые узлы, от которых и пойдет дальнейшая пляска


 
ДьяволСД   (2006-10-18 11:27) [10]

Можно сделать что если узел не найден то делать корнем.


 
Amoeba ©   (2006-10-18 11:44) [11]

http://www.delphikingdom.com/asp/viewitem.asp?catalogid=783


 
Сергей М. ©   (2006-10-18 12:03) [12]


> Можно сделать что если узел не найден то делать корнем


Хм ... В базе элемент дерева числится как дочерний, а в TreeView он вдруг ни с того ни с сего выглядит корневым ? Ну и разве это правильно ? Подумай ... Дело даже не в том как это визуально выглядит - такая ситуация чревата серьезными ошибками при дальнейшей модификации базы ..


 
markers ©   (2006-10-18 23:53) [13]

to Сергей М.
Мдя, столкнулся с такой проблемой, почему-то в не находил родителя...
Начал переделывать на рекурсию... Толи чё-то не так делаю (Давно в Дельфях не работал и долго в PHP) толи чё.... Вообщем вот код
function catfill(parentid:string="0"; pnod : TTreeNode = nil):Boolean;
 var nod: TTreeNode;
 begin
  ResRow:=DB.exec("SELECT * FROM mag_categories WHERE parentid = "+onequote+
    parentid+onequote+" AND cattype <> "+onequote+"Deleted"+onequote+" ORDER " +
    "BY `name` ASC");
  while not ResRow.eof do
   begin
    nod := Tree.Items.AddChild(pnod,VarToStr(ResRow[4]));
    nod.Data := Pointer(StrToInt(VarToStr(ResRow[0])));
    catfill(ResRow[0],nod);
    ResRow.next;
   end;
 end;

Как я понял вызов построения детей происходит и от туда уже не возвращается..... :( если закоментировать catfill(ResRow[0],nod); то построится дерево подчинёных корню (как и должно быть). Подскажите плиз!


 
Loginov Dmitry ©   (2006-10-19 07:50) [14]

Может здесь че-нить полезного найдешь:

procedure TCardsFrame.BuildTreeByDBData;
var
 MainNode, TempNode, SelectNode: TTreeNode;
 I: Integer;
 NodeList: TList;
 CardData: PCardData;
 AKey: Integer;
begin
 if CardioDM.dstCards.FieldByName("CRD_ID").IsNull then
   AKey := -1
 else
   AKey := CardioDM.dstCards.FieldByName("CRD_ID").AsInteger;
   
 DBTreeView.Items.BeginUpdate;
 ClearData;
 DBTreeView.Items.Clear;

 // Создаем корень дерева
 MainNode := DBTreeView.Items.AddChild(nil, "Все картотеки");
 with MainNode do
 begin
   ImageIndex := 1;
   SelectedIndex := 1;
 end;
 SelectNode := MainNode;

 NodeList := TList.Create;
 try
   with CardioDM.dstCards do
   begin
     First;
     while not Eof do
     begin
       TempNode := DBTreeView.Items.AddChild(MainNode, FieldByName("CRD_NAME").AsString);
       with TempNode do
       begin
         New(CardData);
         FillChar(CardData^, SizeOf(TCardData), 0);
         CardData^.cdKey := FieldByName("CRD_ID").AsInteger;
         if CardData^.cdKey = AKey then SelectNode := TempNode;
         if not FieldByName("CRD_OWNERID").IsNull then
           CardData^.cdOwnerKey := FieldByName("CRD_OWNERID").AsInteger;
         if not FieldByName("CRD_DATE").IsNull then
           CardData^.cdDate := FieldByName("CRD_DATE").AsDateTime;
         Data := CardData;
       end;

       // Добавляем новый итем в список
       NodeList.Add(TempNode);
       Next;
     end;
     // Упорядочиваем итемы в соответствии в CRD_OWNERID
     for I := 0 to NodeList.Count - 1 do
       TTreeNode(NodeList[I]).MoveTo(FindParentNode(TTreeNode(NodeList[I])), naAddChild);

   end;
 finally
   NodeList.Free;
   DBTreeView.Items.EndUpdate;
 end;

 // Выделяем необходымый итем
 DBTreeView.Selected := SelectNode;
end;



Страницы: 1 вся ветка

Текущий архив: 2006.11.05;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.043 c
15-1160773435
Иксик
2006-10-14 01:03
2006.11.05
Зотов


15-1160934483
vidiv
2006-10-15 21:48
2006.11.05
Атом Неона (знатокам химии/физики)


2-1161258865
Dr. Genius
2006-10-19 15:54
2006.11.05
Строковое $-представление числа


2-1161627334
Busik
2006-10-23 22:15
2006.11.05
Помогите програмисты,это очень важно для меня


1-1159112496
dreamse
2006-09-24 19:41
2006.11.05
Подключение ActiveX к проекту