关于 TreeView 控件的操作。(50分)

  • 主题发起人 主题发起人 iCANK
  • 开始时间 开始时间
I

iCANK

Unregistered / Unconfirmed
GUEST, unregistred user!
数据库中有这样的字段:
id date
1 20020103
2 20020105
3 20020109

date 字段代表日期,比如第一条记录代表 2002年1月3日。程序初始化时,读数据库,在
TreeView 里面实现下面的树:

2002 年
|__ 01 月
|__ 03 日
|__ 05 日
|__ 09 日
……
其中,DayNode.Data := Pointer(id);

现在用户增加一个记录,记录日期假如为 20020108,我现在的做法是先把数据入库,在重新
初始化 TreeView 一次,但这样太慢了。有没有办法在 05日 和 09日之间插入一个DayNode呢?

我想主要是要找到插入点的问题。因为用户可能不是在插入前不是选择 2002年1月5日,是要由
程序自动找到 2002年1月5日再在后面插入的。
 
当然有了,
TreeView1.Items.AddNode(....)可以
TreeView1.Items.Insert(...)也可以
TreeView1.Items.InsertNode(...)也可以
具体看一下帮助,你就明白了
 
var
Node1,Node2:TTreeNode;
i:integer;
begin
table1.first;
for i:=0 to table1.recordcount-1 do
begin
Node1:=TreeView1.items.add(nil,copy(table1.fieldbyname('data').asstring,0,4))+'年');
Node2:=TreeView2.items.AddChild(Node1,copy(table1.fieldbyname('data').asstring,5,2))+'月');
TreeView2.items.AddChild(Node2,copy(table1.fieldbyname('data').asstring,7,2))+'日');
end;
table1.next;
end;
 
twos:
我知道有这些函数,但是关键是怎么找到插入点啊。

HLHGOD:
你的代码还是把数据库中的数据重新初始化一遍啊。我想要找到插入点,然后插入新增
的数据。
 
你可以在各TreeNode的data(指针)中放入如20020602,20020103等数,到tree中遍历一次,就能得到你要插的位置啦!
不要提供源程序吧?
 
to linghua_meng

基本思路知道了,但小人愚笨,一直不成功。如果你有源程序的话,麻烦你贴上来看看,好吗。

谢了。:)
 
看你上面的提示,这个TTreeView应该有三层节点:年、月、日,我不管你的数据库是
怎么样的结构,反正一定有记录日期的。你的TreeView的节点的Data应该指向一个你
自定义的结构,这个结构应该含有一个字符串,用来保存记录的日期。
如: TMyNodeData = record
Date: String;
end;
PMyNodeData = ^TMyNodeData;
那么,增加节点的时候就这样:
var
nd: PMyNodeData;
begin
New(nd);
nd^.Data := xxx.FieldByName('xxx').AsString;
//添加第一个节点
TreeView.AddObjectFirst(nil, FormatDateTime('yyyymmdd',
xxx.FieldByName('xxx').AsDateTime, nd);
end;
插入节点:
var
strFind, strTemp: String;
nd: PMyNodeData;
aNode: TreeNode;
Found: Boolean;
begin
//要插入的记录的日期
strFind := FormatDateTime('yyyymmdd', xxx.FieldByName('xxx').AsDateTime);
strTemp := Copy(strFind, 1, 4);
Found := False;
//第一个节点是年份
aNode := TreeView.GetFirstNode;
while aNode <> nil do
begin
if strTemp = Copy(PMyNodeData(aNode.Data)^.Date, 1, 4) then
begin
Found := True;
break;
end
else //返回下一个兄弟节点
aNode := GetNextSibling
end;
if not Found then
begin
//如果没找到与该记录同年的第一层节点,那么创建一个该年份的节点
//然后在该节点下创建月份、日期的节点
exit;
end;
//找到了
Found := False;
//查找第一个子节点(月份)
aNode := aNode.GetFirstChild;
……
//过程跟上面的一样,判断所有的兄弟节点有没有符合的
//没有就创建节点
end;
我不知道你的TreeView导入数据库的时候那些节点是否是排序的,如:
-2000
|___01
|___02
|___07
|___23
|___09
-2001
|___02
|___08
-2002
|___01
|___03
|___08
如果是,那就更好办,判断的时候,多加一个节点变量,记录同一层节点中的前后两个
节点,如: Node1, Node2。Node1是Node2的前一个兄弟节点,那么,在判断年份的时候,
Node1 := TreeView.GetFirstNode;
Node2 := Node1.GetNextSibling:
if strFind = Copy(PMyNodeData(Node1.Data)^.Date, 1, 4) then
FindNode := Node1;//返回Node1
if strFind = Copy(PMyNodeData(Node2.Data)^.Date, 1, 4) then
FindNode := Node2;//返回Node2
if (strFind > Copy(PMyNodeData(Node1.Data)^.Date, 1, 4)) and
(strFind < Copy(PMyNodeData(Node2.Data)^.Date, 1, 4)) then
InsertNode := Node2;//返回Node2
if FindNode <> nil then
begin
//TreeView中存在这节点
end
else
if InsertNode <> nil then
begin
//不存在这个节点,要添加,刚好插入在Node2的前面
TreeView.InsertObject(.....);
end;
====================
写的比较乱,而且也没用程序实践,不过思路大概是这样:
查找第一层节点(年),没有这年的节点,就插入这年的节点,
然后在该年份节点下创建该记录月份的子节点,然后再在月份节点
创建该日的子节点;
有该年的节点,查找它的子节点,没有该月份子节点,创建……;
有该月份节点,在下面插入子节点(如果每日不只一条记录,那么
就在该日的节点下插入子节点);
在释放TreeView的时候,不要忘了是否每个节点的Data指向的内存空间:
在TreeView的OnDeletion事件中,释放内存:
var
p: PMyNodeData;
if Node.Data <> nil then
begin
p := Node.Data;
DisPose(p);
p := nil;
end;
 
自己修改一下就可以用了:)

procedure TForm1.Button1Click(Sender: TObject);
var
i,j,k:integer;
y,m,d:string;
fy,fm,fd:boolean;
adn:TTreeNode;
begin
// decodedate(strtodate(edit1.text)
y := copy(Edit1.Text,1,4);
m := copy(Edit1.Text,5,2);
d := copy(Edit1.Text,7,2);
fy := false;
fm := false;
fd := false;
for i := 0 to TreeVIew1.Items.Count - 1 do
begin
if treeview1.Items.Item.Text = y then
begin
fy := true;
for j := i to TreeVIew1.Items.Count - 1 do
begin
if treeview1.Items.Item[j].Text = m then
begin
fm := true;
for k := j to TreeVIew1.Items.Count - 2 do
begin
if (treeview1.Items.Item[k].Text > d) and (treeview1.Items.Item[k + 1].Text < d) then
begin
fd := true;
TreeView1.Items.Insert(treeview1.Items.Item[k],d);
exit;
end;
end;
if not fd then
TreeView1.Items.AddChild(treeview1.Items.Item[j],d);
exit;
end;
end;
if not fm then
begin
adn := TreeView1.Items.AddChild(treeview1.Items.Item,m);
TreeView1.Items.AddChild(adn,d);
end;
end;
end;
if not fy then
begin
adn := TreeView1.Items.AddChild(nil,y);
adn := TreeView1.Items.AddChild(adn,m);
TreeView1.Items.AddChild(adn,d);
end;
 
后退
顶部