Treeview的小问题 |
答題得分者是:william
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
TTreeView is the treeview.
TTreeNodes is a collection of nodes of a treeview.
TTreenode is a node inside a treeview. e.g.
Assume TreeView1 is a treeview.
TreeView1.Items is a TTreeNodes.
TreeView1.Selected is a TTreeNode. if TreeView1.Selected.Level=0 then
{ selected node is a root node} { showing the index of the selected node }
ShowMessage(TreeView1.Selected.AbsoluteIndex);
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
谢谢先进!你的回答很精彩,其实我现在遇到的问题是想把数据库里面的资料分层次的显示在TreeView上,是这样的,我先显示最上层的,然后在显示第二层,然后在显示第三层.......我的程序如下,但是始终没有如愿,本来每一层下面都有子节点的,但是我的程式没有达到那样的要求,应该怎么作呢?
procedure TForm1.FormShow(Sender: TObject);
var i,m:integer;
key:string;
ddd:Tstrings;
begin
with query1 do
begin
close;
sql.Clear;
unprepare;
sql.Add('select text from linerelation where layer=:layer');
params[0].AsInteger := 1;
prepare;
open
end;
query1.First;
for i:=0 to query1.RecordCount-1 do
begin
treeview1.Items.Add(nil,query1.fieldbyname('text').AsString);
query1.Next;
end;
for i:= 0 to treeview1.Items.Count-1 do
begin
treeview1.Selected := treeview1.Items[i];
with query1 do
begin
close;
sql.Clear;
unprepare;
sql.Add('select key from linerelation where text=:text');
params[0].AsString := treeview1.Items[i].Text;
prepare;
open
end;
key := query1.fieldbyname('key').AsString;
with query1 do
begin
close;
sql.Clear;
unprepare;
sql.Add('select text from linerelation where layer=2 and parent=:key');
params[0].AsString := key;
prepare;
open
end;
query1.First;
for m:=0 to query1.RecordCount-1 do
begin
treeview1.Items.AddChild(treeview1.Items[i],query1.fieldbyname('text').AsString);
query1.Next;
end;
treeview1.Items[i].Expanded := false;
end;
treeview1.Items[0].Expanded := false;
end;
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
Something like that, not tested anyway.... BTW, I think you would better not use RecordCount (not reliable). maybe
while not query1.Eof do begin {....} query.Next; end;and I remember there is a bug in some version of Delphi calling First immediately after opening a query will move the cursor to the 2nd record... You may also be interested in the BeginUpdate and EndUpdate method of TTreeNodes. procedure TForm1.FormShow(Sender: TObject); var i,m:integer; key:string; ddd:Tstrings; ANode: TTreeNode; begin with query1 do begin close; sql.Clear; unprepare; sql.Add('select text from linerelation where layer=:layer'); params[0].AsInteger := 1; prepare; open end; query1.First; for i:=0 to query1.RecordCount-1 do begin treeview1.Items.Add(nil,query1.fieldbyname('text').AsString); query1.Next; end; if treeview1.Items.Count>0 then ANode := treeview1.Items[0] else ANode := nil; while Assigned(ANode) do begin with query1 do begin close; sql.Clear; unprepare; sql.Add('select key from linerelation where text=:text'); params[0].AsString := treeview1.Items[i].Text; prepare; open end; key := query1.fieldbyname('key').AsString; with query1 do begin close; sql.Clear; unprepare; sql.Add('select text from linerelation where layer=2 and parent=:key'); params[0].AsString := key; prepare; open end; query1.First; for m:=0 to query1.RecordCount-1 do begin treeview1.Items.AddChild(ANode,query1.fieldbyname('text').AsString); query1.Next; end; ANode.Expanded := false; ANode := ANode.GetNextSibling; end; treeview1.Items[0].Expanded := false; end; |
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
非常感谢Willian前辈,不过,小弟还有一些疑问,
if treeview1.Items.Count>0 then
ANode := treeview1.Items[0]
else
ANode := nil;
while Assigned(ANode) do
上面的If语句是什么意思呢?还有while Assigned(ANode) do的作用是什么?
ANode := ANode.GetNextSibling这句又是什么意思?
上面的程式只实现了两层,我想实现三层,四层是不是以此类推?
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言: 非常感谢Willian前辈,不过,小弟还有一些疑问, if treeview1.Items.Count>0 then ANode := treeview1.Items[0] else ANode := nil; Get the ROOT node (i.e. the very first node) while Assigned(ANode) do Assigned(ANode) is same as (ANode<>nil) 上面的If语句是什么意思呢?还有while Assigned(ANode) do的作用是什么? ANode := ANode.GetNextSibling这句又是什么意思? Get the next node at the same level. 上面的程式只实现了两层,我想实现三层,四层是不是以此类推? |
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
谢谢!但是我的疑问还没有解决,只有再麻烦前辈了!
下面的代码是查询符合下一层的子节点的条件,所有的节点都放在一个表中。
with query1 do
begin
close;
sql.Clear;
unprepare;
sql.Add('select key from linerelation where text=:text');
params[0].AsString := treeview1.Items[i].Text;
prepare;
open
end;
key := query1.fieldbyname('key').AsString;
with query1 do
begin
close;
sql.Clear;
unprepare;
sql.Add('select text from linerelation where layer=2 and parent=:key');
params[0].AsString := key;
prepare;
open
end;
本来,第三层是在第二层的基础上产生的(两个条件,1:上面第二个查询的layer=3,二:第二个查询的Parent附值为第二层节点的名称(TEXT)),可不可以通过上面的代码直接实现?我想了半天,觉得不可能,重新写代码的话,怎么直接取出第二层节点,然后在在这基础上增加第三层节点呢?不知道我的思路正确否,程式具体应该怎么实现呢?
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
You can search on the treeview (although slow ) < class="code">function GetFirstNode(Level: integer): TTreeNode;
var
i: integer;
f: boolean;
begin
i := 0;
f := False;
while (not f) and (i
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
Thanks William!谢谢前辈!根据你的指点我把程式写完了(下面),达到了我所要的功能,但不知程式是否合理,还请William前辈看看:)
procedure TForm1.FormShow(Sender: TObject);
var i,m,max_layer:integer;
key:string;
ddd:Tstrings;
ANode: TTreeNode;
begin
with query1 do
begin
close;
sql.Clear;
unprepare;
sql.Add('select text from linerelation where layer=:layer');
params[0].AsInteger := 1;
prepare;
open
end;
query1.First;
for i:=0 to query1.RecordCount-1 do
begin
treeview1.Items.Add(nil,query1.fieldbyname('text').AsString);
query1.Next;
end;
with query1 do
begin
close;
sql.Clear;
unprepare;
sql.Add('select max(layer) as maxlayer from linerelation');
prepare;
open
end;
max_layer := query1.fieldbyname('maxlayer').AsInteger;
query1.Close;
for i := 0 to max_layer -1 do
begin
anode := getfirstnode(i);
while Assigned(anode) do
begin
with query1 do
begin
close;
sql.Clear;
unprepare;
sql.Add('select key from linerelation where text=:text');
params[0].AsString := anode.Text;
prepare;
open
end;
key := query1.fieldbyname('key').AsString;
with query1 do
begin
close;
sql.Clear;
unprepare;
sql.Add('select text from linerelation where parent=:key and layer=:layer');
params[0].AsString := key;
params[1].AsInteger := i 2;
prepare;
open
end;
query1.First;
for m:=0 to query1.RecordCount-1 do
begin
treeview1.Items.AddChild(ANode,query1.fieldbyname('text').AsString);
query1.Next;
end;
ANode.Expanded := false;
ANode := ANode.GetNextSibling;
end;
end;
end;
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
linerelation的结构是这样的:key char(6)
parent char(6)
text char(30)
layer int
其中,parent存放的是这条记录的上一节点的代码,key存放的是记录本身的代码,text是那条记录的名称,layer就是该记录所在的层次,layer=0时是根节点,layer=1时第二层,layer=2时是第三层……以此类推。
不过那上面的那段代码,只能解决第一个根节点的所有层次。起他的根节点,只能解决第二层,但是第三层就不能显示出来?
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
Do you mean you have multiple nodes of level 0? I think GetNextSibling (and probably some other GetXXX) can only work on the same tree class="code">function MyGetNextSibling(Node: TTreeNode): TTreeNode;
begin
if Assigned(Node) then
Result := Node.GetNext
else
Result := nil;
while Assigned(Result) and (Node.Level<>Result.Level) do
Result := Result.GetNext;
end;
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
|
Rain
資深會員 發表:31 回覆:236 積分:268 註冊:2003-02-17 發送簡訊給我 |
|
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言: 谢谢< >,不过程序是有点慢就是了,不知前辈能不能给我讲件整个程序的实现思路?特别是你写的那两个函数,简直是太绝了!我也求助了我的一个好朋友,他想了一天多,得出的结论和我一样< >!如果,我想在程序里面加上Image的话,那么该怎么作呢?说真的我是第一次这么深入的用TreeView!麻烦前辈了>>< face="Verdana, Arial, Helvetica"> TTreeView has a Images property (set it to an ImageList). Setting the ImageIndex and SelectedIndex of a TTreeNode should be enough then. The functions I created previously are simply straight forward. All nodes are accessible using TTreeView.Items and the toppest one has an index value of 0 and next one (i.e. index 1, visible or not) is the one below it and so on... For example... treeview1.GetFirstNode = treeview1.Items[0] Node.GetNext = treeview1.Items[Node.AbsoluteIndex 1] Borland's VCL wrapper of treeview is VERY SLOW (hence there are many 3rd party faster treeview components). Your program is slow becasue it needs to search though the treeview and do the insertion. |
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言: William前辈,还有没有更好一点的算法,因为如果表linerelation中的记录多了,那么频繁的操作,速度肯定会受影响,你认为呢?If linerelation is generated by somebody else, I think you probably want to build the treeview node by node instead of layer by layer in order to minimize searching through the treeview. If linerelation is used only to store the tree structure, as Rain said, it would be better to use the SaveToStream, SaveToFile, LoadFromStream, LoadFromFile method of treeview. |
railgunman
初階會員 發表:59 回覆:121 積分:36 註冊:2003-03-31 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |