Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.11.05;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.048 c
15-1161146287
Layner
2006-10-18 08:38
2006.11.05
WindowsXP: один раз вошел в домен, теперь локально работаю


6-1150219083
Интересующийся
2006-06-13 21:18
2006.11.05
Как определьть IP указывающий основной шлюз?


1-1159177313
Alex_C
2006-09-25 13:41
2006.11.05
Как сохранить цветовое выделение текста в TRichEdit?


15-1160386826
Сало
2006-10-09 13:40
2006.11.05
Крамник-Топалов


15-1160644299
Desdechado
2006-10-12 13:11
2006.11.05
Пара вопросов по VS 2005





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский