关于TTreeView的使用(300分)

  • 主题发起人 主题发起人 DickWu
  • 开始时间 开始时间
D

DickWu

Unregistered / Unconfirmed
GUEST, unregistred user!
我在使用TTreeView时对有些地方不是很清楚,
1.TTreeView的节点是不是能写入其他的信息?
比如一个节点我想给它赋个10的值,当我点击该节点时,就从该节点中
取出该值. 希望给个例程,另外,好象我没找到TTreeView的OnSelect
事件,不知道,当我选择了一个节点时,在那个事件中来判断 ?
(本问题100分)

2.我有一个Record数组,其中有3个Integer数据.
TMyRecord=record
Root: integer;
Middle: integer;
Foot:integer;
end;
TaMyRecord=Array of TMyRecord;

例如该动态数组从数据库中装入5条记录
[1,3,1] [1,5,2] [1,5,1]
[3,1,2] [3,2,5]
我想组成这样一个TTreeview的结构:

|-Root (Root = 1 )
| |
| |--Middle (Root=1 and Middle=3)
| | |
| | |--Foot [1,3,1]
| |
| |__Middle [1,5]
| |
| |--Foot [1,5,2]
| |--Foot [1,5,1]
|
|-Root [3]
|
|--Middle [3,1]
| |
| |--Foot [3,1,2]
|
|__Middle [3,2]
|
|--Foot [3,2,5]

就是说,我想先按Root值归类,再把同一Root值下的记录按Middle归类,
以此来组织TreeView的结构.
这些数组按数据库中的数据动态生成的,TreeView显示时不一定要索引.

请各位大侠给一个好一点的实例程序(本问题200分)
 
第一个问题:
使用TTreeNode.Data存储你的数据指针,就可以访问。
在TTreeView.OnChange时间中通过判断Selected是否为nil,可以知道有没有选择新的节点。
第二个问题也很简单:假设你的TreeView是tv
procedure InsertNodes(r: TMyRecord);
var
tnTmp: TTreeNode;
found: boolean;
begin
tnTmp := tv.Items.GetFirstNode;
found := false;
while (tnTmp <> nil) and (not found) do begin
if tnTmp.Data = Pointer(r.Root) then begin
found := true;
tnTmp := tnTmp.GetNext;
end;

if not found then begin
tnTmp := tv.Items.Add(nil, .....);
tnTmp.Data := Pointer(r.Root);
end; //加好了Root

.........以下重复两次同样的算法,就可以将Middle和Foot加好。
end;
 
// 下面是我用过的一个对TreeView操作的单元, 希望对你能有所帮助
// 它是从哪来的,我记不清了,只记得修改了一下,
// 其中的Bookmark是用来记录对应记录的位置的, 它存放在TTreenode.data中,

unit TreeFunc;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, ComCtrls, DB, Forms, Dialogs;

function TreeFindItem(Sender: TTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
function FindNode(Sender: TTreeView; Name: String): TTreeNode;
function TreeAddItem(Sender: TTreeView; ItemList: TStrings; Bookmark: TBookmark; Resort: Boolean): TTreeNode;
function TreeGetItem(Sender: TTreeView; ItemList: TStrings): TTreeNode;
procedure TreeDeleteItem(Sender: TTreeView; ItemList: TStrings; Level: Integer);

implementation


function TreeAddItem(Sender: TTreeView; ItemList: TStrings; Bookmark: TBookmark; Resort: Boolean): TTreeNode;
var
ThisNode, Node: TTreeNode;
I: Integer;
begin
Node := nil; //nil = level 0 has no parent node
//this is checked by TreeFindItem
for I := 0 to Itemlist.count -1 do
begin
ThisNode := TreeFindItem(Sender, node, Itemlist);
if ThisNode <> nil then Node := ThisNode
else
begin
if I < Itemlist.count -1 then
begin
if I = 0 then Node := Sender.items.Add(Node, Itemlist)
else Node := Sender.items.AddChild(Node, Itemlist);
end else
begin
if I = 0 then Node := Sender.items.AddObject(Node, Itemlist, Bookmark)
else Node := Sender.items.AddChildObject(Node, Itemlist, Bookmark);
end;
Node.stateIndex := Node.level + 1;
if Resort and (Node.parent <> nil) then Node.parent.alphasort;
end;
end;
Result := Node;
end;

function TreeFindItem(Sender: TTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
begin
if NodeItem = nil then NodeItem := Sender.items.getfirstnode
else NodeItem := NodeItem.getfirstchild;
//NodeItem is now the first item of the desired level
//if this level has no items, NodeItem is nil

if (NodeItem <> nil) and (NodeItem.text <> Name) then
repeat
NodeItem := NodeItem.getnextsibling;
until (NodeItem = nil) or (NodeItem.text = Name);
Result := NodeItem;
end;

function FindNode(Sender: TTreeView; Name: String): TTreeNode;
var
node:ttreenode;
i:integer;
begin
node:=nil;
for i:=0 to sender.Items.Count-1 do
begin
node:=sender.Items;
if node.Text=name then
begin
break;
end
else
node:=nil;
end;
result:=node;
end;

function TreeGetItem(Sender: TTreeView; ItemList: TStrings): TTreeNode;
begin
Result := TreeAddItem(Sender, Itemlist, nil, false);
end;

procedure TreeDeleteItem(Sender: TTreeView; ItemList: TStrings; Level: Integer);
var
Node, Parent: TTreeNode;
begin
Node := TreeGetItem(Sender, ItemList);
while Node.level >= Level do
begin
Parent := Node.parent;
Node.delete;
if (Parent = nil) or (Parent.hasChildren) then break;
Node := Parent;
end;
end;


end.
 
jim 是对的, 用onchange就可以代替onselect, 从treeview.selected得到
选择的treenode.
 
哇!来晚了,没什么可补充的。
 
呵呵,多谢指点, amo和Jim各加120分,cytown也给个友情60分 :)
 
这么快吗?
既然好不容易入来就顺便说一句,
在第一个问题上,用DATA引用时可以用这样的句式:
var
i:integer;
p:^integer;
begin
...
p:=item.data;
I:=P^
...

还可以这样:
var
i:integer;
begin
...
i:=(PInteger(Item.data))^

-------------------------------------------
现在你可以结束问题了。
 
多人接受答案了。
 
后退
顶部