建TREEVIEW问题!(重分)(200分)

  • 主题发起人 flashwolf
  • 开始时间
F

flashwolf

Unregistered / Unconfirmed
GUEST, unregistred user!
遇到一问题,表中有两个字段
userid和parentid,userid表示用户名,parentid表示userid的上一级用户的用户名。
现在要用fctreeview建一个treeview的树。
原先用一种递归算法,但数据超过100条后运行就非常非常的慢,要等半天树才显示。
有何好办法?
附:原来的代码:
procedure TMainForm.CreateMyTree();
var
TreeNode: TfcTreeNode;
tmpsql: string;
node_num: Integer;
// 节点序号
begin
Current_uID := GUserId;
Current_uName := GUserName;
Current_GrpID := 0;
// departid := '';
tmpsql := 'select * from user_info';
with dm1.qryuser_info do
begin
Close;
SQL.Clear;
SQL.Add(tmpSql);
Open;
First;
end;
TVManager.Items.Clear;
{ remove any existing nodes }
node_num := 0;
TreeNode := nil;
CreateNode(@node_num, '', TreeNode);
end;

///////////////////////////
procedure TmainForm.CreateNode(node_num: PInteger;
parent: string;
TreeNode: TfcTreeNode);
var
userid, ChildName: string;
RecordCount: integer;
IsFirstChild: boolean;
begin
RecordCount := 0;
IsFirstChild := True;
dm1.qryuser_info.First;
while not dm1.qryuser_info.eof do
begin
if dm1.qryuser_info.fieldbyname('flag').asinteger <> 1 then
begin
with TVManager.Items do
begin
if (Trim(dm1.qryuser_info.fieldbyname('parentid').asstring) = parent) then
begin
ChildName := Trim(dm1.qryuser_info.fieldbyname('name').asstring);
if IsFirstChild then
begin
TreeNode := AddChild(TreeNode, ChildName);
IsFirstChild := False;
end
else
TreeNode := Add(TreeNode, ChildName);
userid := Trim(dm1.qryuser_info.fieldbyname('userid').asstring);
TVManager.items[node_num^].StringData := userid;
// 将登录用户设为初始节点
if userid = GUserId then
GUserNode := TreeNode;
node_num^ := node_num^ + 1;
CreateNode(node_num, userid, TreeNode);
end;

end;
end;
RecordCount := RecordCount + 1;
dm1.qryuser_info.First;
dm1.qryuser_info.moveby(RecordCount);
end;
end;
 
你找一个现成的控件DBTreeView,先了解一下。
可以到yahoo上查找。
 
没精力看你的源码,做过实现,相同的条件, TfcTreeView的速度更快。
 
没错,我就是用了1stclass的控件TfcTreeView,但搞不定啊,非常急,在线等待。
 
用devexpress的DBTREEVIEW,他有优化算法,非常快,只要设置几个FIELD属性就
解决问题
 
没时间换控件了,好多模块都用到fcTreeView了,所以不能换。
方法无非也就是两个
TreeNode := Add(TreeNode, Name);
加同级节点
TreeNode := Addchild(TreeNode, Name);加子级节点
NAME为节点所显示的ID。
 
谁能搞定啊?????非常非常急!!!!!![:(!][:(!][:(!]
 
递归是非常慢的:(
建个层次字段,先构建第一层显示,下面的可以用线程或等用户点击时再构建。
我这儿有个表9000多记录,递归要4分钟:(。
 
'select * from user_info'中的*可以用别的代替一下
select flag,parentid,name,userid from user_info
如果你不需要全部的子段的化,可能能节约一点时间
 
不行,没用的,还是慢。
 
这是kevin给出的一个代码你可以参考一下
treeview的加速读取
Srm:=TSrmObject.Create(Fn,fmOpenReadWrite);
Msh:=TMemoryStream.Create;
Msd:=TMemoryStream.Create;
Srm.LoadIndex(Msh,Msd);
AList := TStringList.Create;
TreeView.Items.begin
Update;
AList.LoadFromStream(Msh);
SendMessage(TreeView.Handle, TVM_DELETEITEM, 0, Longint(TVI_ROOT));
AOldLevel := 0;
AParentNode := nil;
n:=AList.Count-1;
p:=Msd.Memory;
for i:=0 to n do
begin
StrBuf:=PChar(AList.Strings);
ALevel:=0;
//得该项所在层数
while StrBuf^=#9 do
begin
Inc(StrBuf);
Inc(ALevel);
end;
//返回该项的上级节点
if (ALevel<AOldLevel) or (AParentNode<>nil) then
begin
for j:=AOldLevel do
wnto ALevel do
begin
AParentNode:=AParentNode.Parent;
end;
end;
AParentNode:=TreeView.Items.AddChildObject(AParentNode,StrBuf,
pointer(p.Pos));
AParentNode.ImageIndex:=p.DataType;
AOldLevel:=ALevel;
p:=pointer(integer(p)+sizeof(TTreeData));
end;
TreeView.Items.EndUpdate;
AList.Free;
Msd.Free;
Msh.Free;
 
顶部