欢迎大家讨论TreeView,无限级(或者有限级),如何设计和实现。

net_morning 2008-07-21 10:42:40
欢迎大家讨论TreeView,无限级(或者有限级),如何设计和实现。
以前用DBTreeView,不是很理想。
欢迎各位朋友讨论。
...全文
174 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
五哥 2008-08-06
  • 打赏
  • 举报
回复
AGroupFram.tvGroup: 是TTreeView;

AGroupDirs:是一个结构或者类 ,用于存放Data的,你自己需要把什么放到data中,就定义什么样子的

其他的就没什么啦 。
net_morning 2008-08-05
  • 打赏
  • 举报
回复
cai5大侠你好,能否解释一下那几个在该函数中没有定义的变量?非常感谢
net_morning 2008-08-05
  • 打赏
  • 举报
回复
三级的话,是否可以不用递归呢?
wmm1977 2008-07-23
  • 打赏
  • 举报
回复
treeview里面数据多了,慢的很,级次多了也不好,3-5级即可,最好用编码位数控制级次
lake_cx 2008-07-21
  • 打赏
  • 举报
回复
首次填充两级,以后用户展开一级填充展开节点下一级的下一级,一直保证有一级缓冲就行了
虽然写起来麻烦点,不过对于数据量大小都适用。。。
JeffChung 2008-07-21
  • 打赏
  • 举报
回复
好像没有多少东西可以讨论的,都差不多吧。关键看数据库怎么设计

一般用id和pid,
有些设计是只用id,比如父节点的id是01,然后id是0101,0102....的就是它的子节点
byteh 2008-07-21
  • 打赏
  • 举报
回复
递归,如果数据量很大,就根据选择的node逐步加载
mdejtod 2008-07-21
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20080703/17/e6cbf9be-dccf-448b-bb4c-a41ca1c48eae.html

排版不好看,有点乱,有点多...不过效果还行,没有拖动功能
五哥 2008-07-21
  • 打赏
  • 举报
回复


你把加上去的每个节点的.data都给附上数据库中的id,
到你选择的时候,你把它的data取出来,取到id就可以啦,
data的类型为指针,你最好构造一个Record,再定义一个指针。

type
PR : ^R ;
R = record
id : integer ; //id
NodeText : string ;//节点Text值
end ;

var
p : PR ;
node : TTreeNode ;
begin
new(p) ;

try
p^.id := .. ;
p^.NodeText := .. ;
node := TreeView1.Items.Add(....) ;或者 node := TreeView1.Items.AddChild(....) ;
node.Data := p ;
finally
dispose(p) ;
end;

end;


读取时,
var
p : PR ;
id :integer ;
nodeText : String ;
begin
new(p) ;
try
if TreeView1.Selected <> nil then
begin
if (TreeView1.Selected.Data <> nil ) then
betin
p :=(PR)TreeView1.Selected.Data ;
id := p^.id ;
nodeText := p^.NodeText ;
end;
end;
finally
dispose(p) ;
end;

end;

直接在这里面写的,你自己看看,我也不知道有没有问题,家里没有环境写。
五哥 2008-07-21
  • 打赏
  • 举报
回复
你把加上去的每个节点的.data都给附上数据库中的id,
到你选择的时候,你把它的data取出来,取到id就可以啦,
data的类型为指针,你最好构造一个Record,再定义一个指针。

type
PR : ^R ;
R = record
id : integer ; //id
NodeText : string ;//节点Text值
end ;

var
p : PR ;
node : TTreeNode ;
begin
new(p) ;

try
p^.id := .. ;
p^.NodeText := .. ;
node := TreeView1.Items.Add(....) ;或者 node := TreeView1.Items.AddChild(....) ;
node.Data := p ;

end;
net_morning 2008-07-21
  • 打赏
  • 举报
回复
谢谢各位,深入思考中。树的数据量不大,组织结构树。另外,点击节点时候,判断该节点的ID,目前的方法是根据节点的text值,select数据库中的id,但这样有个问题,不同分支的节点,很有可能text相同。有没有更好的办法获得节点的ID。
lmjloavcj1 2008-07-21
  • 打赏
  • 举报
回复
首次填充两级,以后用户展开一级填充展开节点下一级的下一级,一直保证有一级缓冲就行了
虽然写起来麻烦点,不过对于数据量大小都适用。。。

QQ:200895969
QQ:200895969
EMAIL:200895969@QQ.COM
yuehaiyang 2008-07-21
  • 打赏
  • 举报
回复
用id和pid比较方便些,如果数据量比较大还是不要用递归。
JeffChung 2008-07-21
  • 打赏
  • 举报
回复
一般是递归,节点数量太大就不要用,用一级缓冲按需生成。

如果是数据库结果是这样的,不需要递归也可:
01
0101
0102
010201
02
0201
...
因为只要一排序,父节点总在子节点前面,只要看自身id的长度跟上一条id的长度关系就知道是父子还是兄弟了
阿三 2008-07-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 net_morning 的回复:]
用递归 和 只用id,比如父节点的id是01,然后id是0101,0102....的就是它的子节点,
不知道这两个方案哪个更合适一些。深入思考中。比如这样的结构:中国大陆,华南区,广东,广州。

[/Quote]
数据库的设计是一方面,但实现的算法还是算用递归吧。对于只用id的这种也要用递归来实现吧
net_morning 2008-07-21
  • 打赏
  • 举报
回复
用递归 和 只用id,比如父节点的id是01,然后id是0101,0102....的就是它的子节点,
不知道这两个方案哪个更合适一些。深入思考中。比如这样的结构:中国大陆,华南区,广东,广州。
五哥 2008-07-21
  • 打赏
  • 举报
回复

procedure TCustFormX.LoadGroupDir(billid: Integer; node: TTreeNode);
var
i: Integer;
nodechild, nodeparent: TTreeNode;
begin
AGroupFram.tvGroup.Items.BeginUpdate;
if billid = 0 then
begin
if node = nil then
begin
for i := 0 to AGroupDirs.Count - 1 do
begin //根节点
if TAGroupDir(AGroupDirs[i]).Parent = 0 then
begin
nodeparent := AGroupFram.tvGroup.Items.Add(node, TAGroupDir(AGroupDirs[i]).CName);
nodeparent.Data := AGroupDirs[i];
LoadGroupDir(billid, nodeparent);
end;
end;
end
else
begin
for i := 0 to AGroupDirs.Count - 1 do
begin //子节点
if TAGroupDir(AGroupDirs[i]).Parent = TAGroupDir(node.Data).TreeId then
begin
nodechild := AGroupFram.tvGroup.Items.AddChild(node, TAGroupDir(AGroupDirs[i]).CName);
nodechild.Data := AGroupDirs[i];
LoadGroupDir(billid, nodechild);
end;
end;
end;
end
else
begin
if node = nil then
begin
for i := 0 to AGroupDirs.Count - 1 do
begin //根节点
if (TAGroupDir(AGroupDirs[i]).Parent = 0) and (TAGroupDir(AGroupDirs[i]).BillId = billid) then
begin
nodeparent := AGroupFram.tvGroup.Items.Add(node, TAGroupDir(AGroupDirs[i]).CName);
nodeparent.Data := AGroupDirs[i];
LoadGroupDir(billid, nodeparent);//递归调用
end;
end;
end
else
begin
for i := 0 to AGroupDirs.Count - 1 do
begin //子节点
if (TAGroupDir(AGroupDirs[i]).Parent = TAGroupDir(node.Data).TreeId) and (TAGroupDir(AGroupDirs[i]).BillId = billid) then
begin
nodechild := AGroupFram.tvGroup.Items.AddChild(node, TAGroupDir(AGroupDirs[i]).CName);
nodechild.Data := AGroupDirs[i];
LoadGroupDir(billid, nodechild));//递归调用
end;
end;
end;
end;
AGroupFram.tvGroup.Items.EndUpdate;
AGroupFram.tvGroup.FullExpand;
end;

五哥 2008-07-21
  • 打赏
  • 举报
回复
使用递归,不管你的级数有多少,节点数量多少。

5,930

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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