treeview控件添加、删除节点问题?(50分)

  • 主题发起人 wangchengwu
  • 开始时间
W

wangchengwu

Unregistered / Unconfirmed
GUEST, unregistred user!
那位高手能给我实现以下树的添加、删除节点功能?
1。
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, DB, ADODB, Mask, DBCtrls, ExtCtrls;

type
TForm1 = class(TForm)
TreeView1: TTreeView;
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
new: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure FormCreate(Sender: TObject);
procedure newClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
function loadcode(treeDB:TADOTable):integer;
function getlevel(sformat,scode:string):integer;
{ Public declarations }
end;

var
Form1: TForm1;
tv:ttreenode;

const
scodeformat = '322222'; //科目代码结构
sfirstnodetxt = '科目代码'; //首节点显示的文字

implementation

{$R *.dfm}

function tform1.loadcode(treeDB:TADOTable):integer;
var
nowid,sname,showtxt:string;
i,level:integer;
mynode:array[0..6]of ttreenode;
begin
screen.cursor:=crhourglass;
level:=0;
with treeDB do
begin
try
if not active then open;
first;
TreeView1.items.clear;
mynode[level]:=TreeView1.items.add(TreeView1.topitem,sfirstnodetxt);
mynode[level].imageindex:=0;
mynode[level].selectedindex:=0;
while not eof do
begin
nowid:=trim(fieldbyname('acode').asstring);
showtxt:=nowid+'------------'+fieldbyname('aname').asstring;
level:=getlevel(scodeformat,nowid);
if level> 0 then
begin
mynode[level]:=TreeView1.items.addchild(mynode[level-1],showtxt);
mynode[level].imageindex:=1;
mynode[level].selectedindex:=2;
end;
next;
end;
finally
close;
end;
end;
mynode[0].expand(false);
screen.cursor:=crdefault;
end;

function tform1.getlevel
(sformat,scode:string):integer;
var i,level,ilen:integer;
begin
level:=-1;
ilen:=0;
if (sformat<>'')and(scode<>'')then
for i:=1 to length(sformat) do
begin
ilen:=ilen+strtoint(sformat);
if length(scode)=ilen then
begin
level:=i;
break;
end;
end;
result:=level;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
with ADOTable1 do
begin
open;
indexfieldnames:='acode';
end;
loadcode(ADOTable1);
end;













2。
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, DB, ADODB, Mask, DBCtrls, ExtCtrls, Menus;
const
cTreeCodeFormat='122222';
cTreeMaxLevel=6;
cTreeRootTxt='单位字典';

type
TForm1 = class(TForm)
TreeView1: TTreeView;
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
DataSource1: TDataSource;
DBEdit1: TDBEdit;
DBEdit2: TDBEdit;
Button1: TButton;
PopupMenu1: TPopupMenu;
Add1: TMenuItem;
Delete1: TMenuItem;
Edit1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure Add1Click(Sender: TObject);
procedure Delete1Click(Sender: TObject);
procedure Edit1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure LoadTree(treeDB:TADOTable);
procedure UpdateTree(curNode:TTreenode;nodeTxt:string;state:string);
function GetNodeLeveL(sFormat,sCode:string):integer;
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.GetNodeLeveL(sFormat,scode:string):integer;
var i,level,iLen:integer;
begin
level:=-1;
iLen:=0;
if (sFormat<>'') and (sCode<>'') then
for i:=1 to length (sformat) do
begin
iLen:=iLen+StrToInt(sFormat);
if length(sCode)=iLen then
begin
level:=i;
break;
end;
end;
result:=level;
end;

procedure TForm1.LoadTree(treeDB:TADOTable);
var
curID,nodeTxt:string;
level:integer;
mynode:array[0..6] of TTreenode;
begin
TreeView1.Enabled:=true;
TreeView1.Items.clear;
level:=0;
TreeView1.items.clear;
mynode[level]:=TreeView1.Items.add(TreeView1.Topitem,cTreeRootTxt);
mynode[level].ImageIndex :=1;
with TreeDB DO
begin
try
if not Active then open;
first;
while not Eof do
begin
curID:=trim(FieldByName('code').Asstring);
nodeTxt:=curID+'-'+trim(FieldByName('name').Asstring);
level:=GetNodelevel(cTreeCodeFormat,curID);
if level>0 then
begin
mynode[level]:=TreeView1.items.addchild(mynode[level-1],nodeTxt);
mynode[level].imageIndex:=2;
end;
next;
end;
finally;
close;
end;
mynode[0].expand(true);
end;
end;

procedure TForm1.UpdateTree(curNode:TTreenode;nodeTxt:string;state:string);
begin
if state='add' then
begin
curNode:=TreeView1.items.addchild(curNode,nodeTxt);
curNode.imageIndex:=2;
end;
if state='del' then curNode.delete;
if state='edi' then curNode.text:=NodeTxt;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
with ADOTable1 do
begin
open;
indexFieldNames:='code';
active:=true;
end;
LoadTree(ADOTable1);
end;
 
我说一个最笨的办法,当你对结点进行添加,删除,更改完毕以后,可以先把所有的结点清空,
再重新加载一遍,就不用考虚那么多的问题了,
 
头大。。。
 
难道没高手吗?
 
没有注释的代码怎么看,怎么帮你?
 
你是要增加、删除节点后把再保存回数据库吧。
采用这种思路吧。构造两字段,一个为节点ID,一个为父结点ID
ID ParentID
010000 000000
010100 010000
010101 010100
010102 010100
010200 010000
010201 010200

给你提供我写的两个函数把数据挂到树上,增删后再根据点关系把数据保存回去。
如果在数据集中找不到记录,就增加,如果在树中找不到记录,就删除,如果在
找到了但与树中文本不对就修改。

//成树函数
procedure TFrmBaseOneTree.createtree(Fcds:Tclientdataset;Ftv:TTreeview;Fstr:string;
sender:Tfrmbaseonetree;Fi:integer);
var j,k,i,f:integer;
streeparent,streeid:string;
v: Pointer;
PNode:Ttreenode;
begin
if Fcds.RecordCount=0 then
exit;
Fcds.First;
while not Fcds.Eof do
begin
new(v);
v:=sender.CreateRecordStru(Fi);
f:=0;
k:=Fcds.RecNo;
streeparent:=Fcds.fieldbyname('treeparent').AsString;
streeid:=Fcds.fieldbyname('treeid').AsString;
Fcds.First;

for i:=1 to k-1 do
begin
if Fcds.FieldByName('treeid').AsString=streeparent then
begin
f:=i;
end;
Fcds.Next;
end;
if f<>0 then
begin
Ftv.Items[f-1].Selected:=true;
PNode:=Ftv.Items.AddChild(Ftv.Selected,trim(Fcds.FieldByName(Fstr).AsString));
PNode.Data:=v;
end
else
begin
Ftv.Selected:=nil;
PNode:=Ftv.Items.Add(Ftv.Selected,trim(Fcds.FieldByName(Fstr).AsString));
PNode.Data:=v;
end;
Fcds.RecNo:=k;
Fcds.Next;
end;
try
Ftv.FullExpand;
ftv.Items[0].Selected:=true;
except

end;
end;

 
[?]还有呢?
 
没人答吗?
 
昨天刚做了一个

create table TEST( BH NUMBER, FBH NUMBER, MC VARCHAR2(10));
测试的数据
declare
begin
--execute immediate 'drop teble test';

delete from test;
insert into test (bh,fbh,mc)values( 1,0,'A');
insert into test (bh,fbh,mc)values( 2,1,'B');
insert into test (bh,fbh,mc)values( 3,1,'C');
insert into test (bh,fbh,mc)values( 4,2,'D');
insert into test (bh,fbh,mc)values( 5,2,'E');
insert into test (bh,fbh,mc)values( 6,0,'F');
insert into test (bh,fbh,mc)values( 7,2,'G');
insert into test (bh,fbh,mc)values( 8,3,'H');
insert into test (bh,fbh,mc)values( 9,4,'I');
insert into test (bh,fbh,mc)values(10,0,'J');
insert into test (bh,fbh,mc)values(11,1,'l');
insert into test (bh,fbh,mc)values(12,2,'M');
insert into test (bh,fbh,mc)values(13,3,'N');
insert into test (bh,fbh,mc)values(14,4,'O');
insert into test (bh,fbh,mc)values(15,12,'P');
insert into test (bh,fbh,mc)values(16,13,'Q');
insert into test (bh,fbh,mc)values(17,16,'R');
insert into test (bh,fbh,mc)values(18,16,'S');
insert into test (bh,fbh,mc)values(19,17,'T');
insert into test (bh,fbh,mc)values(20,17,'U');
commit;
end;

 
成树过程
procedure TForm1.Button2Click(Sender: TObject);
var
i,fbh :integer;
curNode : TTreeNode; //当前节点
mc,s1 :string;
begin
TreeView1.Items.Clear;
tQuery.Close;
tQuery.SQL.Text := 'select count(*) count from test';
tQuery.Open;
DS.Close;
DS.SQL.Text:='select distinct fbh from test order by fbh';
DS.Open;
repeat
fbh := ds.FieldByName('fbh').AsInteger;
tQuery.Close;
tQuery.SQL.Text := 'select * from test where bh ='+IntToStr(fbh);
tQuery.Open;
mc := tQuery.FieldByName('mc').AsString;
if ds.FieldByName('fbh').AsInteger = 0 then
curNode := nil
else
begin
for i:= 0 to TreeView1.Items.Count-1 do
begin
TreeView1.Items.Selected := true ;
s1 := TreeView1.Selected.Text;
if s1 = mc then
break;
end;
curNode := TreeView1.Selected ;
end;
tQuery.Close;
tQuery.SQL.Text := 'select * from test where fbh ='+IntToStr(fbh);
tQuery.Open;
if tQuery.RecordCount = 0 then
TreeView1.Items.AddChild(nil,'根结点')
else
repeat
TreeView1.Items.AddChild(curNode,UpperCase(tQuery.FieldByName('mc').AsString));
tQuery.Next;
until tQuery.Eof;
ds.Next;
until ds.Eof ;
tQuery.Close;
tQuery.SQL.Text := 'select * from test order by fbh,bh';
tQuery.Open;
end;
 
删除结点过程,我是用Oracle的存贮过程来完成的
create or replace procedure p_delete_test
(
in_bh in integer
)
as
ibh integer;
begin
declare
cursor c_zjd is select bh from test where fbh = in_bh;
begin
open c_zjd;
fetch c_zjd into ibh;
if c_zjd%notfound then
delete from test where bh = in_bh ;
commit;
end if;

while c_zjd%found loop
dbms_output.put_line(ibh);
p_delete_test(ibh);
fetch c_zjd into ibh;
end loop;
close c_zjd;
delete from test where bh = in_bh ;
commit;
end;
end;
 
顶部