Форум: "Начинающим";
Текущий архив: 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.49 MB
Время: 0.056 c