向周末坚守岗位的程序员问好!!!!我向各位请教!treeview 动态生成的效率 我的数据表字段 ID,pid(父结点),subject(内容)大概有4000条,我用动态形成,速度不能忍受,各位有何高见?或点在结点上再显示?有好办法吗?谢谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你不能分队段吗?form建立时建第一层在点击时判断有没有子节点,如有看子节点是否建立,如未则建立我的2600多节点就是这样建的,一次性建太慢也没必要 同意先加入根节点,判断有无子节点,设置该节点HasChildren属性, 需要看下一级子节点时候,在onExpanding事件里再加入下一级子节点,一层一层加。 好像有一个Lock属性,设置为True然后添加完成后把他设置为假速度会有很大提高 如果在在onExpanding事件里再加入下一级子节点,那么当我第二次点击“+”的时候,是否还要再生成一遍? 用写文件的方式很快TreeView.LoadFromFile('*.txt')当然必须有写的过程! procedure TFrmCommodifyMaintenance.InitTV();var Depart1_No : String[EditDepart1_Len]; Depart2_No : String[EditDepart2_Len]; Depart3_No : String[EditDepart3_Len]; Commodify_No: String[CommodityNo_Len]; Tree_SPXX: TStrings;// Query_Temp : TQuery;begin DM_Data.QueryTemp.DisableControls; Tree_SPXX := TStringList.Create; try FrmPassword.CB_Temp.Items.clear; FrmPassword.CB_Temp.Items.Add(Market_Name); Tree_SPXX.Clear; Tree_SPXX.Add(Market_Name); DM_Data.TableDepart1.First; while Not DM_Data.TableDepart1.Eof do begin Depart1_No:= DM_Data.TableDepart1.fieldbyname('DepartNo1').AsString; FrmPassword.CB_Temp.Items.Add(#9+DM_Data.TableDepart1.FieldByName('Department1').AsString); Tree_SPXX.Add(Depart1_No); DM_Data.TableDepart2.Filter := 'DepartNo1='''+Depart1_No+''''; DM_Data.TableDepart2.First; while Not DM_Data.TableDepart2.Eof do begin Depart2_No:= DM_Data.TableDepart2.fieldbyname('DepartNo2').AsString; FrmPassword.CB_Temp.Items.Add(#9#9+DM_Data.TableDepart2.FieldByName('Department2').AsString); Tree_SPXX.Add(Depart1_No+Depart2_No); DM_Data.TableDepart3.Filter := 'DepartNo1='''+Depart1_No+''' and DepartNo2='''+Depart2_No+''' and Availability=1'; DM_Data.TableDepart3.First; while Not DM_Data.TableDepart3.Eof do begin Depart3_No:= DM_Data.TableDepart3.fieldbyname('DepartNo3').AsString; FrmPassword.CB_Temp.Items.Add(#9#9#9+DM_Data.TableDepart3.FieldByName('Department3').AsString); Tree_SPXX.Add(Depart1_No+Depart2_No+Depart3_No); with DM_Data.QueryTemp do begin Active:=False;// DatabaseName := 'Market_DSN'; SQL.Clear; SQL.Add('SELECT Commodify.DepartNo1, Commodify.DepartNo2, Commodify.DepartNo3, Commodify.CommodifyNo, Commodify.FullName'); SQL.Add('FROM Commodify'); SQL.Add('where (Commodify.DepartNo1 = '''+Depart1_No+''')'); SQL.Add(' AND (Commodify.DepartNo2 = '''+Depart2_No+''')'); SQL.Add(' AND (Commodify.DepartNo3 = '''+Depart3_No+''')'); SQL.Add('ORDER BY Commodify.DepartNo1, Commodify.DepartNo2, Commodify.DepartNo3, Commodify.CommodifyNo'); Active:=True; while Not Eof do begin Commodify_No:=DM_Data.QueryTemp.FieldByName('CommodifyNo').AsString; if Trim(Commodify_No)<>'' then begin FrmPassword.CB_Temp.Items.Add(#9#9#9#9+DM_Data.QueryTemp.FieldByName('FullName').AsString); Tree_SPXX.Add(Depart1_No+Depart2_No+Depart3_No+Commodify_No); end; Next; end; end; DM_Data.TableDepart3.Next; end; DM_Data.TableDepart2.Next; end; DM_Data.TableDepart1.Next; end; DM_Data.TableDepart2.Filter := ''; DM_Data.TableDepart3.Filter := 'Availability = 1'; FrmPassword.CB_Temp.Items.SaveToFile(SysPath+'Tmp_Data\Temp.txt'); TV.LoadFromFile(SysPath+'Tmp_Data\Temp.txt'); FrmPassword.CB_Temp.Items := Tree_SPXX; FrmPassword.CB_Temp.Items.SaveToFile('c:\Temp.txt'); Tree_SPXX.Clear; finally Tree_SPXX.Free; DM_Data.QueryTemp.Active:=False; DM_Data.QueryTemp.EnableControls; end;end; //载入时不刷新界面~~ Table1.DisableControls; TreeView1.Items.BeginUpdate; try { TODO : 动态载入 } finally TreeView1.Items.EndUpdate; Table1.EnableControls; end;//----------------我比较喜欢用Text方式来处理数型数据~~利用TTreeView.LoadFromStream();TTreeView.SaveToStream();这个方法来可以数据的字段交换数据~~主要是存储方便~~不用写太多的代码处理~~如果需要保存其他信息~~可以看成简单的文本来处理~~ 递归的方法在数据量比较小的时候比较还可以,如果数据量大了的话,请用以下方法: 数据集和TreeView procedure LoadTree(treeDB:TDBDataSet);//初始化树 procedure UpdateTree(curNode:TTreenode; nodeTxt:string; state:string);//更新树function GetNodeLevel(sFormat,sCode:string):integer; //获得节点层数function GetNodeItem(sCode:string):integer;//获得item{ Public declarations }end;constCTreeCodeFormat='122222';cTreeMaxLevel=6;CTreeRootTXT='所有图书';vartsgzlfrom: Ttsgzlfrom;_err:integer;curUser:string[10];mystate:string;gNodeId:string;gNodelevel:integer;gNode:TtreeNode;mynode:array[0..6] of TTreenode;i,Already,CurMode:integer;currow:integer;iniFile:string;HasSub:String;level:Integer; implementationuses bgNewunit; {$R *.DFM}procedure TtsgzlFrom.LoadTree(treeDB:TDBDataSet);//初始化树var curID,nodeTxt:string;level,num:integer;begin//初始化变量Screen.Cursor:=crHourGlass;tree.Enabled:=True;tree.Items.Clear;level:=1 ;num:=1;tree.items.clear;//设置根节点mynode[level]:=Tree.items.add(Tree.Topitem,cTreeRootTxt);mynode[level].ImageIndex:=0;mynode[level].SelectedIndex:=1;//遍历数据表,利用编码字段记录排序规律,依次添加树节点with TreeDb dobegintryif not Active then open;first;while not Eof dobegincurID:=trim(FieldByName('tsglb').AsString);nodeTxt:=curID+'-'+trim(FieldByName('tsglbn').AsString);level:=GetNodeLevel(cTreeCodeFormat,curID);//这里返回代码的层次数if level>0 thenbegin//增加下一节点时,用添加子节点的方法可轻松实现节点间的层次关系。//注意:这里的父节点是用当前节点的上一级节点mynode[level-1]mynode[level]:=Tree.Items.AddChild(Mynode[level-1],NodeTxt);mynode[level].ImageIndex:=2;mynode[level].SelectedIndex:=3;end;next;//下一条记录end;finally;close;End;mynode[1].expand(False);Screen.Cursor:=crHourGlass;end;end;function TtsgzlFrom.GetNodeLevel(sFormat,sCode:string):integer;var i,iLen:integer;beginlevel:=-1 ;iLen:=0;if (sFormat<>'') and (sCode<>'') thenfor i:=1 to Length(sFormat) do //分析编码格式,找出当前代码层次beginiLen:=iLen+StrToInt(sFormat[i]);if Length(sCode)=iLen thenbeginlevel:=i;break;end;end;result:=level;end;Function TtsgzlFrom.GetNodeItem(sCode:string):integer;//获得itemvar i,iCount,val:integer;tmp:string;beginResult:=0;iCount:=Tree.Items.Count;if iCount=0 then exit;val:=0;for i:=1 to iCount-1 dobeginTmp:=Tree.Items.Item[i].Text;Tmp:=Copy(Tmp,0,pos('-',Tmp)-1);if Tmp=sCode then beginval:=i;Break;end;end;result:=val;end;procedure TtsgzlFrom.UpdateTree(curNode:TTreenode; nodeTxt:string; state:string);Beginif state='add' thenbegincurNode:=Tree.Items.addchild(curNode,nodeTxt);curNode.ImageIndex:=2;curnode.SelectedIndex:=3;end;if state='del' then curNode.delete;if state='edi' then curNode.Text:=nodeTxt;end; 楼上的TREEVIEW的形成好象必须挨顺序存再挨顺序读吧! 在数据库里加children字段,如》0就设HASCHILDREN=TRUE,可以的 请大家帮帮忙,为什么使用Setkey会出错, ORACLE、SQL SERVER技术资料网站 我如何可以取到OpenDialog1 打开选择上的文件的文件名? ★★★★★★★★★怎样获得一个文本框中光标所在的位置,在线等待,解决给分!!★★★★★★★★★ 怎樣去掉在注冊表中已經編譯的中間層服務器的名稱 有谁知道李维的个人网站么?谢谢 小问题 textout问题。 ★★★ 急急急,高手请进!!!!!! 关于Delphi一个BUG的讨论 极其简单的入门问题!再线!!!! 头好疼,树的遍历,请教各位!
form建立时建第一层
在点击时判断有没有子节点,如有看子节点是否建立,如未则建立
我的2600多节点就是这样建的,一次性建太慢也没必要
TreeView.LoadFromFile('*.txt')
当然必须有写的过程!
var
Depart1_No : String[EditDepart1_Len];
Depart2_No : String[EditDepart2_Len];
Depart3_No : String[EditDepart3_Len];
Commodify_No: String[CommodityNo_Len];
Tree_SPXX: TStrings;
// Query_Temp : TQuery;
begin
DM_Data.QueryTemp.DisableControls;
Tree_SPXX := TStringList.Create;
try
FrmPassword.CB_Temp.Items.clear;
FrmPassword.CB_Temp.Items.Add(Market_Name);
Tree_SPXX.Clear;
Tree_SPXX.Add(Market_Name);
DM_Data.TableDepart1.First;
while Not DM_Data.TableDepart1.Eof do begin
Depart1_No:= DM_Data.TableDepart1.fieldbyname('DepartNo1').AsString;
FrmPassword.CB_Temp.Items.Add(#9+DM_Data.TableDepart1.FieldByName('Department1').AsString);
Tree_SPXX.Add(Depart1_No);
DM_Data.TableDepart2.Filter := 'DepartNo1='''+Depart1_No+'''';
DM_Data.TableDepart2.First;
while Not DM_Data.TableDepart2.Eof do begin
Depart2_No:= DM_Data.TableDepart2.fieldbyname('DepartNo2').AsString;
FrmPassword.CB_Temp.Items.Add(#9#9+DM_Data.TableDepart2.FieldByName('Department2').AsString);
Tree_SPXX.Add(Depart1_No+Depart2_No);
DM_Data.TableDepart3.Filter := 'DepartNo1='''+Depart1_No+''' and DepartNo2='''+Depart2_No+''' and Availability=1';
DM_Data.TableDepart3.First;
while Not DM_Data.TableDepart3.Eof do begin
Depart3_No:= DM_Data.TableDepart3.fieldbyname('DepartNo3').AsString;
FrmPassword.CB_Temp.Items.Add(#9#9#9+DM_Data.TableDepart3.FieldByName('Department3').AsString);
Tree_SPXX.Add(Depart1_No+Depart2_No+Depart3_No);
with DM_Data.QueryTemp do begin
Active:=False;
// DatabaseName := 'Market_DSN';
SQL.Clear;
SQL.Add('SELECT Commodify.DepartNo1, Commodify.DepartNo2, Commodify.DepartNo3, Commodify.CommodifyNo, Commodify.FullName');
SQL.Add('FROM Commodify');
SQL.Add('where (Commodify.DepartNo1 = '''+Depart1_No+''')');
SQL.Add(' AND (Commodify.DepartNo2 = '''+Depart2_No+''')');
SQL.Add(' AND (Commodify.DepartNo3 = '''+Depart3_No+''')');
SQL.Add('ORDER BY Commodify.DepartNo1, Commodify.DepartNo2, Commodify.DepartNo3, Commodify.CommodifyNo');
Active:=True;
while Not Eof do begin
Commodify_No:=DM_Data.QueryTemp.FieldByName('CommodifyNo').AsString;
if Trim(Commodify_No)<>'' then begin
FrmPassword.CB_Temp.Items.Add(#9#9#9#9+DM_Data.QueryTemp.FieldByName('FullName').AsString);
Tree_SPXX.Add(Depart1_No+Depart2_No+Depart3_No+Commodify_No);
end;
Next;
end;
end;
DM_Data.TableDepart3.Next;
end;
DM_Data.TableDepart2.Next;
end;
DM_Data.TableDepart1.Next;
end;
DM_Data.TableDepart2.Filter := '';
DM_Data.TableDepart3.Filter := 'Availability = 1';
FrmPassword.CB_Temp.Items.SaveToFile(SysPath+'Tmp_Data\Temp.txt');
TV.LoadFromFile(SysPath+'Tmp_Data\Temp.txt');
FrmPassword.CB_Temp.Items := Tree_SPXX;
FrmPassword.CB_Temp.Items.SaveToFile('c:\Temp.txt');
Tree_SPXX.Clear;
finally
Tree_SPXX.Free;
DM_Data.QueryTemp.Active:=False;
DM_Data.QueryTemp.EnableControls;
end;
end;
Table1.DisableControls;
TreeView1.Items.BeginUpdate;
try
{ TODO : 动态载入 }
finally
TreeView1.Items.EndUpdate;
Table1.EnableControls;
end;//----------------
我比较喜欢用Text方式来处理数型数据~~
利用
TTreeView.LoadFromStream();
TTreeView.SaveToStream();
这个方法来可以数据的字段交换数据~~
主要是存储方便~~
不用写太多的代码处理~~
如果需要保存其他信息~~
可以看成简单的文本来处理~~
数据集和TreeView
procedure LoadTree(treeDB:TDBDataSet);//初始化树
procedure UpdateTree(curNode:TTreenode; nodeTxt:string; state:string);//更新树function GetNodeLevel(sFormat,sCode:string):integer; //获得节点层数function GetNodeItem(sCode:string):integer;//获得item{ Public declarations }end;constCTreeCodeFormat='122222';cTreeMaxLevel=6;CTreeRootTXT='所有图书';vartsgzlfrom: Ttsgzlfrom;_err:integer;curUser:string[10];mystate:string;gNodeId:string;gNodelevel:integer;gNode:TtreeNode;mynode:array[0..6] of TTreenode;i,Already,CurMode:integer;currow:integer;iniFile:string;HasSub:String;level:Integer; implementationuses bgNewunit; {$R *.DFM}procedure TtsgzlFrom.LoadTree(treeDB:TDBDataSet);//初始化树var curID,nodeTxt:string;level,num:integer;begin//初始化变量Screen.Cursor:=crHourGlass;tree.Enabled:=True;tree.Items.Clear;level:=1 ;num:=1;tree.items.clear;//设置根节点mynode[level]:=Tree.items.add(Tree.Topitem,cTreeRootTxt);mynode[level].ImageIndex:=0;mynode[level].SelectedIndex:=1;//遍历数据表,利用编码字段记录排序规律,依次添加树节点with TreeDb dobegintryif not Active then open;first;while not Eof dobegincurID:=trim(FieldByName('tsglb').AsString);nodeTxt:=curID+'-'+trim(FieldByName('tsglbn').AsString);level:=GetNodeLevel(cTreeCodeFormat,curID);//这里返回代码的层次数if level>0 thenbegin//增加下一节点时,用添加子节点的方法可轻松实现节点间的层次关系。//注意:这里的父节点是用当前节点的上一级节点mynode[level-1]mynode[level]:=Tree.Items.AddChild(Mynode[level-1],NodeTxt);mynode[level].ImageIndex:=2;mynode[level].SelectedIndex:=3;end;next;//下一条记录end;finally;close;End;mynode[1].expand(False);Screen.Cursor:=crHourGlass;end;end;function TtsgzlFrom.GetNodeLevel(sFormat,sCode:string):integer;var i,iLen:integer;beginlevel:=-1 ;iLen:=0;if (sFormat<>'') and (sCode<>'') thenfor i:=1 to Length(sFormat) do //分析编码格式,找出当前代码层次beginiLen:=iLen+StrToInt(sFormat[i]);if Length(sCode)=iLen thenbeginlevel:=i;break;end;end;result:=level;end;Function TtsgzlFrom.GetNodeItem(sCode:string):integer;//获得itemvar i,iCount,val:integer;tmp:string;beginResult:=0;iCount:=Tree.Items.Count;if iCount=0 then exit;val:=0;for i:=1 to iCount-1 dobeginTmp:=Tree.Items.Item[i].Text;Tmp:=Copy(Tmp,0,pos('-',Tmp)-1);if Tmp=sCode then beginval:=i;Break;end;end;result:=val;end;procedure TtsgzlFrom.UpdateTree(curNode:TTreenode; nodeTxt:string; state:string);Beginif state='add' thenbegincurNode:=Tree.Items.addchild(curNode,nodeTxt);curNode.ImageIndex:=2;curnode.SelectedIndex:=3;end;if state='del' then curNode.delete;if state='edi' then curNode.Text:=nodeTxt;end;