急,关于TreeView源码?!看看吧(50分)

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

fullstrong

Unregistered / Unconfirmed
GUEST, unregistred user!
我建有一个数据库文件,该库文件数据主要是用TreeView来进行显示,该库结构如下:

Parent SubKey Subject_Text
0 001 a
0 002 B
001 00101 C
002 00201 c1
0 003 A1
001 00102 D


在TreeView中显示的结构应为:

---树结构------
|
|---a
| |
| |---C
| |---D
|---B
| |
| |-C1
|
|---A1

我编写的代码如下:

type
PMyTree = ^TMyTree;
TMyTree = record //用于存放树节点的ID(subkey)
TreeSubKey: string;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
//从库中调用数据到TreeView
WITH TblCategories do
begin
TblCategories.DatabaseName:=ParamStr(1); //指向应用程序所在路径
TblCategories.TableName:='Categories.db';
TblCategories.open;
end;
LoadCode(TblCategories);
end;


function TMainForm.LoadCode(crTbl:TDBDataSet):Integer;
var
ShowTxt:String;
Node:TtreeNode;
MyTreePtr: PMyTree;
Par_ID:String;
begin
New(MyTreePtr);
with crTbl do
begin
try
if not Active then Open;
First;
TreeView1.Items.Clear; //以下是增加第一项
Node:=TreeView1.Items.Add(TreeView1.TopItem,'类别树');
MyTreePtr^.TreeSubKey:='0';
node.data:=MyTreePtr;
While Not Eof do
begin
MyTreePtr^.TreeSubKey:=Trim(FieldByName('SubKey').AsString);
Par_ID:=Trim(FieldByName('Parent').AsString);
ShowTxt:=Trim(FieldByName('Subject_Text').AsString);
node:=FindParentNode(Par_ID);
node:=TreeView1.Items.AddChild(Node, ShowTxt);
node.data:=MyTreePtr;
Next;
end;
finally
Close;
end;
end;
end;

Function TMainForm.FindParentNode(Parent_ID:String):TtreeNode;
Var
i:integer;
TreePtr: PMyTree;
Parent_key:string;
begin
Result:=nil;
For i:=0 to TreeView1.Items.count-1 do
begin
TreePtr:=TreeView1.Items.Data;
Parent_Key:=Trim(TreePtr^.TreeSubKey);
if Parent_Key=Parent_ID then
begin
Result:=TreeView1.Items;
Break;
end;
end;
end;

结果在TreeView中显示的为下图:
---树结构------
|
|---a
|---C
|---D
|---B
|---C1
|---A1

不知为何成这样,难道是FindParentNode()有问题吗? 在下在这里请各位DELPHI高手帮我看看,
到底是何处出错了? 谢谢!!
 
函数Function TMainForm.FindParentNode(Parent_ID:String):TtreeNode;Var
有问题!
为什么
Result:=TreeView1.Items;
Break;
永远不会执行?

你再检查一遍,我也继续分析!

 
错误找到了!
你注意以下不妨在findparentnode中加入一个showmessage();
TreePtr:=TreeView1.Items.Data;
Parent_Key:=Trim(TreePtr^.TreeSubKey);
showmessage(TreeView1.Items.Text +' '+parent_key);
会发现所有的 Parent_key都相同!
为什么呢?
因为你的所有data指向的都是同一个Mytreeptr,所以最后的结果肯定是最后一次的赋值结果!
至于解决的办法吗?我继续想!
 
错误很明显嘛。MyTreePtr针对与每个TreeNode都要New一次。
While Not Eof do
begin
MyTreePtr^.TreeSubKey:=Trim(FieldByName('SubKey').AsString);
Par_ID:=Trim(FieldByName('Parent').AsString);
ShowTxt:=Trim(FieldByName('Subject_Text').AsString);
<font color=red>New(MyTreePtr); //I add
MyTreePtr^.TreeSubKey:=Trim(FieldByName('SubKey').AsString);//I add</font>
node:=FindParentNode(Par_ID);
node:=TreeView1.Items.AddChild(Node, ShowTxt);
node.data:=MyTreePtr;
Next;
end;
请指正。
 
独孤求败,高手,一眼看穿了!
不过它的程序还是。。
因为
MyTreePtr^.TreeSubKey:=Trim(FieldByName('SubKey').AsString);一句它写了两遍
(嘿嘿,瑕不掩瑜吗!)把前面的一句去掉就可以了!

fullstrong:你的表格设计有问题:

001 00102 D
应为
00101 00102 D




 
<font color=red> 怎么出现红色?
 
to xiuguo:
呵呵,高手不敢当。我的确看错了。其实把New。。。这一句放到第一行就行了。
真是不好意思,^o^

 
为什么不用integer型作为Parent和Subkey类型,这样,直接在
node:=TreeView1.Items.AddChildObject(Node, ShowTxt, ParentKey);
不是很方便么?

另外,最好使用TQuery来读取数据:
SELECT Parent,SubKey,Subject_Text FROM Categories ORDER BY Parent, SubKey
这样,就不会有漏掉的了。否则,可能会把一些节点漏掉,如果它的父节点
出现在它后面。
 
DreamTiger:有道理!
难怪,分数那么高!
 
你可以把它写成空件用TQuery来读取

以下是我朋友的一段代码可能会对你有帮助
procedure TGroupTree.SetGroupField(const Value: String);
Var
Root, GNode, SubNode: TTreeNode;
Qry1, Qry2: TQuery;
i, j: Integer;
KeyValue: PNodeInfo;
begin
if Value=FGroupField then
if NOT FRefresh then Exit;
FGroupField := Value;
// if FGroupField='' then FGroupField:='*';
Qry1:=TQuery.Create(Nil);
Qry2:=TQuery.Create(Nil);
FTreeView.Items.BeginUpdate;
FTreeView.Items.Clear;
Root:=FTreeView.Items.AddFirst(Nil,FRootName);
Root.ImageIndex:=0;
Root.SelectedIndex:=1;
New(KeyValue);
KeyValue.ndValue:= StrAlloc(Length(FRootName));
StrCopy(KeyValue.ndValue, PCHAR(FRootName));
KeyValue.ndClass:= ncRoot;
Root.Data:=KeyValue;
Try
Qry1.DatabaseName:=FSourceTable.DatabaseName;
Qry2.DatabaseName:=FSourceTable.DatabaseName;
Qry1.SQL.Add(format(SQLGroup,[FGroupField, FSourceTable.TableName, ChangeFileExt(FSourceTable.TableName,''), FGroupField]));
Qry1.Open;
For i:=0 to Qry1.RecordCount-1 do
begin
GNode:=FTreeView.Items.AddChild(Root,Qry1.FieldByName(FGroupField).AsString);
GNode.ImageIndex:=2;
GNode.SelectedIndex:=3;
New(KeyValue);
KeyValue.ndClass:= ncDir;
GNode.Data:= KeyValue;
Qry2.SQL.Clear;
Qry2.SQL.Add(Format(SQLGroupSet,[FKeyField, FCaptionField, FSourceTable.TableName, ChangeFileExt(FSourceTable.TableName,'') , FGroupField, Qry1.FieldByName(FGroupField).AsString]));
Qry2.Open;
For j:=0 to Qry2.RecordCount-1 do
begin
SubNode:=FTreeView.Items.AddChild(GNode,Qry2.FieldByName(CaptionField).ASString);
SubNode.ImageIndex:=4;
SubNode.SelectedIndex:=5;
New(KeyValue);
KeyValue.ndValue :=StrAlloc(Qry2.FieldByName(FKeyField).DataSize);
Qry2.FieldByName(FKeyField).GetData(KeyValue.ndValue);
KeyValue.ndClass:= ncFile;
SubNode.Data:=KeyValue;
Qry2.Next;
end;
Qry1.Next;
end;
Finally
TreeView.Items.EndUpdate;
Qry1.Close; Qry1.Free;
Qry2.Close; Qry2.Free;
end;
end;
 
谢谢大家!
 
后退
顶部