2023年6月22日发(作者:)
Delphi实现树型结构⽣成树型结构有2种⽅法:1.动态⽣成树结点2.静态⽣成树结点这⾥暂不讨论动态⽣成树,先实现静态⽣成!所谓静态⽣成树结点是指通过遍历数据源的⽅式⼀次性把所有树结点全部加载,说起⽣成树避免不了谈起数据库结构的设计。数据库设计的⽅法有2种:1.单编号法单编号法是以每个类为统⼀编号,如其有⼦类,则顺着该编号向后排。如⽔果编号为001,则苹果为⽔果的⼀类,则应为001001等等,这种⽅法易于统计,但不易于维护!如:想要将苹果类变为其它的类,且苹果类下有N层,那会是⼀件⽐较⿇烦的事情!2.双编号法双编号也就是我们经常说的⽤ID与PARENTID来表⽰其⽗⼦关系,维护起来⽐较⽅便,但遍历会稍稍复杂⼀些!⽆论哪种⽅法,⼀般情况下都要创建结构体,并把结构体指针放置到树结点中!因为Treeview的树结点不可能放置更多的信息,我们通常要存该结点的名称(中英⽂)、结点ID、是否为功能结点、⽗结点、图标、选中结点后的图标、dll的名称等等等...以下例⼦: 1 Unit1;
2 ace
3
4 04. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
5 05. Dialogs, StdCtrls, ComCtrls, DB, ADODB;
6
7 07. PNodeInfoEx = ^TNodeInfoEx;
8 08. TNodeInfoEx = Packed Record
9 09. NodeID : Integer;
10 10. ParentID : Integer;
11 11. NodeType : Integer;
12 12. ChnNodeTitle : String;
13 13. ImageIndex: SmallInt;
14 14. SelectedIndex: SmallInt;
15 15. end;
16 16. TForm1 = class(TForm)
17 17. tv1: TTreeView;
18 18. btn1: TButton;
19 19. qry1: TADOQuery;
20 20. procedure btn1Click(Sender: TObject);
21 21. procedure FormDestroy(Sender: TObject);
22 22. private
23 23. { Private declarations }
24 24. function StaticBuildTree(TreeView:TTreeView ):Boolean;
25 25. function AddTreeItem(TreeView:TTreeView; AddNodeInfo:PNodeInfoEx):TTreeNode;
26 26. function FindTreeItem(TreeView:TTreeView; CurNodeID:integer): TTreeNode;
27 27. public
28 28. { Public declarations }
29 29. end;
30
31 31. Form1: TForm1;
32 entation
33 33.{$R *.dfm}
34 34.
35 on BuildTree(TreeView:TTreeView ):Boolean;
36
37 37. AddNodeInfo : PNodeInfoEx; 37 37. AddNodeInfo : PNodeInfoEx;
38
39 39. Result := False;
40 40. omFile('c:/');//这⾥以XML⽂件做为数据源
41 41. pdate;//记住:在进⾏批量添加数据时要使⽤BeginUpdate,来暂时关闭由于添加数据⽽触发的某些事件(如OnChange事件等)
42 42. ;//清空Treeview
43 43. try
44 44. try
45 45. if Count >0 then
46 46. begin
47 47. ;
48 48. while Not do
49 49. begin
50 50. New(AddNodeInfo) ;//⽣成结构体
51 51. AddNodeInfo^.NodeID := yName('NODE_ID').AsInteger;
52 52. AddNodeInfo^.ParentID := yName('PARENT_ID').AsInteger;
53 53. AddNodeInfo^.NodeType := yName('NodeType').AsInteger;
54 54. AddNodeInfo^.ChnNodeTitle := yName('ChnNodeTitle').AsString;
55 55. AddNodeInfo^.ImageIndex := yName('ImageIndex').AsInteger;
56 56. AddNodeInfo^.SelectedIndex := yName('SelectedIndex').AsInteger;
57 57. AddTreeItem(Treeview,AddNodeInfo);//把结构体的指针存到Treeview中
58 58. ;
59 59. end;
60 60. end;
61 61. except
62 62. eBox('⽣成树结点失败',MB_ICONSTOP+MB_OK);
63 63. raise;//向上级抛异常
64 64. end;
65 65. ;
66 66. Result := True;
67 67. finally
68 68. ate;
69 69. end;
70 ;
71 71.//在加⼊结点时,应先判断加⼊的是⽗结点还是⼦结点,判断的依据是在已存在的树结点中是否存在该结点的ParentID
72 on eItem(TreeView:TTreeView; AddNodeInfo:PNodeInfoEx):TTreeNode;
73
74 74. ParentNode: TTreeNode;
75
76 76. ParentNode := FindTreeItem(Treeview,AddNodeInfo^.ParentID);
77 77. If ParentNode <> nil then
78 78. Result := ldObject(ParentNode, Trim(eTitle), Pointer(AddNodeInfo))
79 79. else
80 80. Result := ect(ParentNode, Trim(eTitle), Pointer(AddNodeInfo));
81 81. if Result<>nil then
82 82. begin
83 83. ndex := ndex;
84 84. edIndex := edIndex;
85 85. end;
86 ;
87 87.//这⾥是判断是否存在其⽗结点
88 on eeItem(TreeView:TTreeView; CurNodeID:integer): TTreeNode;
89
90 90. i : Integer;
91
92 92. Result := nil;
93 93. for i := 0 to -1 do
94 94. begin
95 95. if CurNodeID=PNodeInfoEx([i].Data)^.NodeID then
96 96. begin
97 97. Result := [i];
98 98. Exit;
99 99. end;
100 100. end;
101 ;
102 102.//⽣成树结构 102 102.//⽣成树结构
103 ure 1Click(Sender: TObject);
104
105 105. StaticBuildTree (tv1)
106 ;
107 107.//在窗体释放时⼀定要把树结点中的结构体指针给释放掉,对于在Dispose时为什么要进⾏强制转型后释放,以前有专门的讲解,在此不在累述
108 ure stroy(Sender: TObject);
109
110 110. i : Integer;
111
112 112. for i := 0 to -1 do
113 113. begin
114 114. Dispose( PNodeInfoEx([i].Data) )
115 115. end;
116 ;
117 .
118 01.//如何访问树结点?
119 ure 1MouseDown(Sender: TObject; Button: TMouseButton;
120 03. Shift: TShiftState; X, Y: Integer);
121
122 05. pNode:TTreeNode;
123
124 07. pNode:=eAt(x,y);
125 08. if (pNode<>nil) and (Button=mbleft) then
126 09. ShowMessage(PNodeInfoEx()^.ChnNodeTitle);
127 ;
发布者:admin,转转请注明出处:http://www.yc00.com/web/1687386273a6212.html
评论列表(0条)