把树型数据赋给treeview;

internetcsdn 2004-06-29 12:07:54
--数据库为MS SQL
create table tb1(keyid int identity(1,1),parentid int,[name] varchar(20))

insert tb1(parentid,name)
select -1,'李一'
union all select 1,'李二'
union all select 1,'张二'
union all select 3,'张三'
union all select 3,'王三'
union all select 3,'黄三'
union all select -1,'黄1'

select * from tb1
--keyid:主键
--parentid:上层的主键,-1表示顶屋
keyid parentid name
----------------------
1 -1 李一
2 1 李二
3 1 张二
4 3 张三
5 3 王三
6 3 黄三
7 -1 黄1

--drop table tb1
--记录数与层数可动态增加

请问怎样把上表的数据赋给treeview
得到:
-李一
-李二
-张二
-张三
-王三
-黄三
-黄一
...全文
181 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
skm 2004-07-01
  • 打赏
  • 举报
回复

procedure TDBTreeView.DynamicFillSubTree(ANode: TTreeNode);
var
TreeNodes: TTreeNodes;
ParentCode: AnsiString; //the code of ANode
tempNode,tempParentNode: TTreeNode;
NodeText: AnsiString;
NodeData: PAnsiString;
SQLString:AnsiString;
begin
//fill the real Recursive table node or the sub-tree node of the second table
//ANode is current node to fill subtree
NodeText := '';
TreeNodes := Items;
tempParentNode := ANode;
ParentCode := PAnsiString(tempParentNode.Data)^;
if not tempParentNode.HasChildren then //no child
exit;
if Trim(PAnsiString(tempParentNode.getFirstChild.Data)^) <> '' then //this node is not a virtual subnode,has been filled by the really node
exit;
if (TreeKind = tkNoRecursiveOneTable ) then
exit;

//reload the child node
try
//delete the virtual child node of current node
NodeData := PAnsiString(tempParentNode.getFirstChild.Data);
Dispose(NodeData); //free the subnode data
tempParentNode.DeleteChildren;

//reaload the recusinve table node of current node
if (TreeKind = tkRecursiveOneTable )or (TreeKind = tkRecursiveTwoTable ) then
begin
SQLString := 'select '+KeyField+','+DisplayField+','+UpperField+','+LeafField
+' from '+Table+' where '+UpperField+' = '''+ParentCode+''' ';
if Trim(WhereStr) <> '' then
SQLString := SQLString+' and '+WhereStr;
SQLString := SQLString+' order by '+KeyField;
FQuerySet.Close;
FQuerySet.Open(SQLString,KeyField);
FQuerySet.First;
if FQuerySet.RecordCount <= 0 then
begin
FQuerySet.Close; //no Recursive child
end
else
begin
//fill the Recursive node
FQuerySet.First;
while not FQuerySet.Eof do
begin
NodeText := FQuerySet.GetFieldValue(KeyField)+'('+FQuerySet.GetFieldValue(DisplayField)+')';
New(NodeData);
NodeData^ := FQuerySet.GetFieldValue(KeyField);
tempNode := TreeNodes.AddChildObject(tempParentNode,NodeText,NodeData);
if FQuerySet.GetFieldValue(LeafField) = true then //value return AsBoolean
begin
tempNode.ImageIndex:= ImgEndIndex;
tempNode.SelectedIndex := ImgEndSelect;
end
else
begin
tempNode.ImageIndex:= ImgGroupIndex;
tempNode.SelectedIndex := ImgGroupSelect;
end;
//additional virtual node just for display and will dynamic fill subtree, if Recursive or twotable
if (TreeKind = tkRecursiveOneTable ) or (TreeKind = tkRecursiveTwoTable ) or (TreeKind = tkNoRecursiveTwoTable ) then
begin
New(NodeData);
NodeData^ := '';
tempNode := TreeNodes.AddChildObject(tempNode,'',NodeData);
tempNode.ImageIndex:= -1;
tempNode.SelectedIndex := -1;
end;
FQuerySet.Next;
end;
end;
end;

//load the SubTable tree node of the current node, sub-table upperfield.value = ParentCode
if (TreeKind = tkNoRecursiveTwoTable ) or (TreeKind = tkRecursiveTwoTable ) then
begin
SQLString := 'select '+SubKeyField+','+SubDisplayField+','+SubUpperField
+' from '+SubTable+' where '+SubUpperField+' = '''+ParentCode+''' ';
if Trim(WhereStr) <> '' then
SQLString := SQLString+' and '+SubWhereStr;
SQLString := SQLString+' order by '+SubKeyField;
FQuerySet.Close;
FQuerySet.Open(SQLString,SubKeyField);
FQuerySet.First;
while not FQuerySet.Eof do
begin
NodeText := FQuerySet.GetFieldValue(SubKeyField)+'('+FQuerySet.GetFieldValue(SubDisplayField)+')';
New(NodeData);
NodeData^ := FQuerySet.GetFieldValue(SubKeyField);
tempNode := TreeNodes.AddChildObject(tempParentNode,NodeText,NodeData);
tempNode.ImageIndex:= ImgSubIndex;
tempNode.SelectedIndex := ImgSubSelect;
FQuerySet.Next;
end;
end;
except
on E: Exception do raise Exception.Create(E.Message);
end;
end;

procedure TDBTreeView.Expand(Node: TTreeNode);
begin
inherited;
if Node.Level =0 then
exit;
DynamicFillSubTree(Node);
end;

procedure TDBTreeView.Change(Node: TTreeNode);
begin
DynamicFillSubTree(Node);
...
inherited;//call the OnChange event
end;

skm 2004-07-01
  • 打赏
  • 举报
回复
給我的例子,可以填充單表遞歸或非遞歸樹,或其葉節點下再掛接另一個單表.
采用只填充當一級子節點方式 ,在Expand或CHANGE節點時調用DynamicFillSubTree(ANode: TTreeNode)動態填充其子節點。
//--------------樹類型
type TTreeKind= (tkNoRecursiveOneTable,tkNoRecursiveTwoTable,tkRecursiveOneTable,tkRecursiveTwoTable);
//--------------------屬性
property Table: AnsiString ; //static single table or view
property KeyField: string ; //single field
property DisplayField:string ;//keyfield(displayfiled)
property UpperField:string ;//the upper filed to Recursive
property LeafField:string ;//the value= true if is a leaf node
//不需要一定有[property WhereStr: AnsiString ;//not contains 'where'
//不需要一定有[ property SubTable: AnsiString ; //static single table or view
//不需要一定有[ property SubWhereStr: AnsiString ;//not contains 'where'
//不需要一定有[ property SubKeyField:string read ; //single field
//不需要一定有[ property SubDisplayField:string ;//keyfield(displayfiled)
//不需要一定有[ property SubUpperField:string ;//the upper filed to Recursive
//-----------------方法---
procedure TDBTreeView.FillTreeWithData;
var
TreeNodes: TTreeNodes;
tempNode,tempParentNode: TTreeNode;
NodeText: AnsiString;
NodeData: PAnsiString;
SQLString:AnsiString;
begin
//donot use Recurse method,just fill one more virtual subnode thus looked like it has sub nodes,
//and dynamic fill the true subnode while selecting the currenet node
TreeNodes := Items;
TreeNodes.Clear;
//create the root node
NodeText := '';
New(NodeData);
NodeData^ := '';
tempParentNode := TreeNodes.AddChildObject(nil,NodeText,NodeData);
tempParentNode.ImageIndex := ImgGroupIndex;
tempParentNode.SelectedIndex := ImgGroupSelect;
try
//single table not Recursive
//fill the first lever nodes,(UpperField.Value = '')
SQLString := 'select '+KeyField+','+DisplayField+','+UpperField+','+LeafField
+' from '+Table+' where '+UpperField+' = '''' ';
if Trim(WhereStr) <> '' then
SQLString := SQLString+' and '+WhereStr;
SQLString := SQLString+' order by '+KeyField;
FQuerySet.Close;
FQuerySet.Open(SQLString,KeyField);
FQuerySet.First;
while not FQuerySet.Eof do
begin
NodeText := FQuerySet.GetFieldValue(KeyField)+'('+FQuerySet.GetFieldValue(DisplayField)+')';
New(NodeData);
NodeData^ := FQuerySet.GetFieldValue(KeyField);
tempNode := TreeNodes.AddChildObject(tempParentNode,NodeText,NodeData);
if FQuerySet.GetFieldValue(LeafField) = true then //value return AsBoolean
begin
tempNode.ImageIndex:= ImgEndIndex;
tempNode.SelectedIndex := ImgEndSelect;
end
else
begin
tempNode.ImageIndex:= ImgGroupIndex;
tempNode.SelectedIndex := ImgGroupSelect;
end;
//additional virtual node just for display and will dynamic fill subtree, if Recursive or twotable
if (TreeKind = tkRecursiveOneTable ) or (TreeKind = tkRecursiveTwoTable ) or (TreeKind = tkNoRecursiveTwoTable ) then
begin
New(NodeData);
NodeData^ := '';
tempNode := TreeNodes.AddChildObject(tempNode,'',NodeData);
tempNode.ImageIndex:= -1;
tempNode.SelectedIndex := -1;
end;
FQuerySet.Next;
end;

//load the SubTable tree node of the first level, sub-table upperfield.value = ''
if (TreeKind = tkNoRecursiveTwoTable ) or (TreeKind = tkRecursiveTwoTable ) then
begin
SQLString := 'select '+SubKeyField+','+SubDisplayField+','+SubUpperField
+' from '+SubTable+' where '+SubUpperField+' = '''' ';
if Trim(WhereStr) <> '' then
SQLString := SQLString+' and '+SubWhereStr;
SQLString := SQLString+' order by '+SubKeyField;
FQuerySet.Close;
FQuerySet.Open(SQLString,SubKeyField);
FQuerySet.First;
while not FQuerySet.Eof do
begin
NodeText := FQuerySet.GetFieldValue(SubKeyField)+'('+FQuerySet.GetFieldValue(SubDisplayField)+')';
New(NodeData);
NodeData^ := FQuerySet.GetFieldValue(SubKeyField);
tempNode := TreeNodes.AddChildObject(tempParentNode,NodeText,NodeData);
tempNode.ImageIndex:= ImgSubIndex;
tempNode.SelectedIndex := ImgSubSelect;
FQuerySet.Next;
end;
end;
//expand the first level
tempParentNode.Expand(false);
Selected := Items.Item[0];
except
on E: Exception do raise Exception.Create(E.Message);
end;

end;
zgq19801123 2004-07-01
  • 打赏
  • 举报
回复
看看
blessbird 2004-07-01
  • 打赏
  • 举报
回复
如果我有多层又该怎么操作?
internetcsdn 2004-06-29
  • 打赏
  • 举报
回复
楼上:
------------------------------------
-张二
-张三
-王三
-黄三
------------------------------------

是说张三,王三,黄三都是张二的子树啊.
因为他们的parentid是3(也就是张二的keyid),不知这样描述清楚不?

fw0011 2004-06-29
  • 打赏
  • 举报
回复
看不出张三,王三,黄三为什么是李一的子树,所以不好写

不过写动态树的话,可提供一例

TreeView1.Items.BeginUpdate;
try
TreeView1.Items.Clear;
with Query do
begin
close;
sql.Clear;
sql.Add('select denumber,detitle from department order by denumber asc');
open;
first;
while not Eof do
begin
node:=TreeView1.Items.AddChild(nil,Query.Fieldbyname('detitle').AsString );

with Querylt do
begin
close;
sql.Clear;
sql.Add('select usname from UserBasicInfo where usdepartmentno=');
sql.Add(''+Query.Fieldbyname('denumber').AsString+'' );

open;
first;
while not Eof do
begin
childnode:=TreeView1.Items.AddChild(node,Querylt.Fieldbyname('usname').AsString );
next;
end;
end;
next;
end;
end;


for i:=0 to TreeView1.Items.Count-1 do
begin
TreeView1.Items[i].SelectedIndex:=1 ;
if TreeView1.Items[i].Level=0 then
TreeView1.Items[i].Expand(True);
end;

finally
TreeView1.Items[0].Selected:=true;

TreeView1.Items.EndUpdate;
end;

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧