我想在程序界面的左边放treeview,然后右边放一个能输入并显示文本的东西。然后我可以自己在左边的treeview上添加或是删除节点,还希望能给右边的输入文本的地方“赋值”。在使用时我只要单击某个节点就能在右边显示出相应的文本内容。
在程序启动时,应当能自动的load上一次使用时的节点信息和相应的右边的文本内容。个位高手,请告诉我右边的那个我该用什么?还有怎样保存节点信息和右边相应的文本内容,使下一次运行程序的时候,能自动load.
在程序启动时,应当能自动的load上一次使用时的节点信息和相应的右边的文本内容。个位高手,请告诉我右边的那个我该用什么?还有怎样保存节点信息和右边相应的文本内容,使下一次运行程序的时候,能自动load.
解决方案 »
- delphi工程问题
- Windows网络编程技术
- 哪位哥能指导一下,用quickreport做报表,怎样能作成横着的,
- 如何在access中动态创建表?
- delphi和sql server的关系
- 谁有reportmachine的rm3.rar文件的解压缩密码,烦请告之,感激不尽,谢谢!
- 谁有类似工序图等的网络图编辑软件?
- Dephi 中如何使用SQL语句改变ACCESS 表的结构
- 建议csdn设立 ‘意见区’,专门收集大家各种意见*(有感于众位大侠要离去)
- 如何定义加入到状态条中的按钮的click事件?
- 有没有详细介绍delphi控件属性,用法的电子书可以下载?一定给分!
- SQL小问题,50分大放送.请帮帮忙忙,在线等待。
procedure Tformproduct.datatotreeview;
var treenodepinpai,treenodesort:Ttreenode;
strbrand:string;//产品品牌
begin
if treeviewp_tree.Items.Count<2 then
with adoqueryproduct do
begin
close;
locktype:=ltOptimistic;
sql.clear;
sql.add('select distinct(sort),brand from product order by brand,sort');
open;
treeviewp_tree.Items.clear;
treenodepinpai:=treeviewp_tree.Items.Add(nil,'产品');
treeviewp_tree.Selected:=treenodepinpai;
treenodepinpai.ImageIndex:=2;
treenodepinpai.stateIndex:=2;
treenodepinpai.SelectedIndex:=3;
formP_add.ComboBoxbrand.Items.Clear;//置添加产品窗体里的comboboxbrand值。
formp_add.comboboxsort.items.clear;
strbrand:='';
while not(eof) do
begin
if (uppercase(fieldbyname('brand').asstring)<>uppercase(strbrand)) then
begin
strbrand:=fieldbyname('brand').asstring;
formp_add.ComboBoxbrand.Items.add(strbrand);
treenodepinpai:=treeviewp_tree.Items.add(nil,strbrand);
treenodepinpai.ImageIndex:=2;
treenodepinpai.stateIndex:=2;
treenodepinpai.SelectedIndex:=3;
end ;
formp_add.ComboBoxsort.Items.Add(fieldbyname('sort').asstring);
treenodesort:=treeviewp_tree.Items.addchild(treenodepinpai,fieldbyname('sort').asstring);
treenodesort.ImageIndex:=0;
treenodesort.stateIndex:=0;
treenodesort.SelectedIndex:=1;
next;
end;//while not(eof) end;//with adoqueryproduct
end;
取结点的
procedure TFormproduct.TreeViewP_treeClick(Sender: TObject);
var treeviewnode,treenodep:Ttreenode;
begin
p_brand:='';
p_sort:='';
p_name:='';
p_type:='';
p_comment:='';
treeviewnode:=treeviewp_tree.Selected;
if treeviewP_tree.Selected.Level=0 then
begin
if treeviewnode.Text<>'产品' then
begin
p_brand:=treeviewnode.text;
end;//if treeivewnode.text='产品'
end else begin //else if treeviewP_tree.selected.level=0
treenodep:=treeviewP_tree.Selected.Parent;
p_brand:=treenodep.text;
p_sort:=treeviewnode.text;
end;//end if treeviewP_tree
end;
与数据库连接,看看第一个回答你的程序,并不难!
弄一个窗口,放上一个TreeView和一个Button,分别取名为TV1和Btn1。如果需要
在每个节点前有个图,请在窗口上放上一个ImageList,取名为ImageList1,双击
它,加入六个图标。还要记得记得将TV1的Images属性改为ImageList1噢。双击按
钮Btn1,在里面填入以下代码,然后按F9运行,点击Btn1就可以看到效果了。
procedure TForm1.Btn1Click(Sender: TObject);
Const
MyDocDir = 'C:\My Documents';
PersonDir = '3hSoft';
Var
Var
I : Word;
SubNodeName : array [1..5] of ShortString;
RootNode, SubNode : TTreeNode;
P : PString;
begin
SubNodeName[1] := '便笺';
SubNodeName[2] := '发件箱';
SubNodeName[3] := '联系人';
SubNodeName[4] := '任务';
SubNodeName[5] := '日记';
TV1.Items.Clear;
TV1.Items.BeginUpdate;
New(P);
P^ := MyDocDir + '\' + PersonDir;
RootNode := TV1.Items.AddObject(Nil, '个人文件夹', P);
// 此 Node 的图标已对 Images 属性中取第 0 个了。
For I := 1 to 5 do
begin
New(P);
P^ := MyDocDir + '\' + PersonDir + '\' + SubNodeName[I];
SubNode := TV1.Items.AddChildObject(RootNode, SubNodeName[I], P)
;
;
// 如果不想使用图标的话请删除以下两行
SubNode.ImageIndex := I;
SubNode.SelectedIndex := I;
end;
TV1.Items.EndUpdate;
end;
二.在TreeView中如何设置选中结点
var
i:integer; {i为设置的选中结点的索引值}
begin
if i>treeview1.items.count then
treeview1.items[i].selected:=true;
或
treeview1.selected:=treeview1.items[i];
三。设置TreeView结点的图形
1. 设置TreeView的images属性为已存在的images对象
treeview1.images:=imagelist1;
2. 在加入结点后执行:
var
anode:TTreeNode;
begein
anode:=Treeview1.add(nil,'item1');
anode.imageindex:=0; {结点未选中时显示的图标}
anode.selectedindex:=1; {结点选中时显示的图标}
end
3. 如果结点图形在改变后未发生变化,可以执行:
treeview1.refresh;
四。如何批量处理TreeView结点
使用TreeView的items属性的BeginUpdate和EndUpdate方法,例:
TreeView1.items.BeginUpdate;
for i:=0 to TreeView1.items.count-1 do
begin
//将每个结点的文字改成为小写字母
TreeView1.items[i].text:=lowercase(TreeView1.items[i].text);
end;
TreeView1.items.EndUpdate; 五。实现TreeView结点拖拽的实例
下面的程序片段演示了如何实现拖拽treeview构件结点的例子
{鼠标按下时执行的语句}
procedure TForm1.Treeview1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
{判断左键按下并且鼠标点在一个结点上开始实现拖拽}
if ( Button = mbLeft ) and
( htOnItem in Treeview1.GetHitTestInfoAt( X, Y ) ) then
begin
Treeview1.BeginDrag( False );
end;
end;
{鼠标拖动执行语句}
procedure TForm1.Treeview1DragOver( Sender, Source: TObject;
X, Y: Integer; State: TDragState; var Accept: Boolean);
var
Node : TTreeNode;
begin
if Source = Treeview1 then
begin
Node := Treeview1.GetNodeAt( X, Y ); {取当前结点}
if Node <> nil then {当前结点不为空才能实现拖拽,accept:=true}
Accept := true;
end;
end;
{鼠标释放时执行的语句}
procedure TForm1.Treeview1DragDrop( Sender, Source: TObject;
X, Y : Integer );
var
TempNode : TTreeNode;
AttachMode : TNodeAttachMode;
begin
if Treeview1.Selected = nil then
Exit;
AttachMode := naAddChild; {设置结点移动模式,设移动结点为子结点}
{ 注意在这里存在一个bug,当移动结点时,如果目标结点没有子结点,}
{ 则加入的新的子结点会失败,所以先在当前目标结点的下面 }
{ 加入一个临时子结点,移动完毕后,再将临时结点删除 }
Treeview1.Items.BeginUpdate;
try
TempNode := Treeview1.Items.AddChild( Treeview1.DropTarget,
'Temp' );
try
{ 移动选中的结点到目标结点 }
Treeview1.Selected.MoveTo( Treeview1.DropTarget, AttachMode );
finally
TempNode.Free; { 不要忘了释放临时结点 }
end;
finally
Treeview1.Items.EndUpdate;
end;
end;
弄一个窗口,放上一个TreeView和一个Button,分别取名为TV1和Btn1。如果需要
在每个节点前有个图,请在窗口上放上一个ImageList,取名为ImageList1,双击
它,加入六个图标。还要记得记得将TV1的Images属性改为ImageList1噢。双击按
钮Btn1,在里面填入以下代码,然后按F9运行,点击Btn1就可以看到效果了。
procedure TForm1.Btn1Click(Sender: TObject);
Const
MyDocDir = 'C:\My Documents';
PersonDir = '3hSoft';
Var
Var
I : Word;
SubNodeName : array [1..5] of ShortString;
RootNode, SubNode : TTreeNode;
P : PString;
begin
SubNodeName[1] := '便笺';
SubNodeName[2] := '发件箱';
SubNodeName[3] := '联系人';
SubNodeName[4] := '任务';
SubNodeName[5] := '日记';
TV1.Items.Clear;
TV1.Items.BeginUpdate;
New(P);
P^ := MyDocDir + '\' + PersonDir;
RootNode := TV1.Items.AddObject(Nil, '个人文件夹', P);
// 此 Node 的图标已对 Images 属性中取第 0 个了。
For I := 1 to 5 do
begin
New(P);
P^ := MyDocDir + '\' + PersonDir + '\' + SubNodeName[I];
SubNode := TV1.Items.AddChildObject(RootNode, SubNodeName[I], P)
;
;
// 如果不想使用图标的话请删除以下两行
SubNode.ImageIndex := I;
SubNode.SelectedIndex := I;
end;
TV1.Items.EndUpdate;
end;
二.在TreeView中如何设置选中结点
var
i:integer; {i为设置的选中结点的索引值}
begin
if i>treeview1.items.count then
treeview1.items[i].selected:=true;
或
treeview1.selected:=treeview1.items[i];
三。设置TreeView结点的图形
1. 设置TreeView的images属性为已存在的images对象
treeview1.images:=imagelist1;
2. 在加入结点后执行:
var
anode:TTreeNode;
begein
anode:=Treeview1.add(nil,'item1');
anode.imageindex:=0; {结点未选中时显示的图标}
anode.selectedindex:=1; {结点选中时显示的图标}
end
3. 如果结点图形在改变后未发生变化,可以执行:
treeview1.refresh;
四。如何批量处理TreeView结点
使用TreeView的items属性的BeginUpdate和EndUpdate方法,例:
TreeView1.items.BeginUpdate;
for i:=0 to TreeView1.items.count-1 do
begin
//将每个结点的文字改成为小写字母
TreeView1.items[i].text:=lowercase(TreeView1.items[i].text);
end;
TreeView1.items.EndUpdate; 五。实现TreeView结点拖拽的实例
下面的程序片段演示了如何实现拖拽treeview构件结点的例子
{鼠标按下时执行的语句}
procedure TForm1.Treeview1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
{判断左键按下并且鼠标点在一个结点上开始实现拖拽}
if ( Button = mbLeft ) and
( htOnItem in Treeview1.GetHitTestInfoAt( X, Y ) ) then
begin
Treeview1.BeginDrag( False );
end;
end;
{鼠标拖动执行语句}
procedure TForm1.Treeview1DragOver( Sender, Source: TObject;
X, Y: Integer; State: TDragState; var Accept: Boolean);
var
Node : TTreeNode;
begin
if Source = Treeview1 then
begin
Node := Treeview1.GetNodeAt( X, Y ); {取当前结点}
if Node <> nil then {当前结点不为空才能实现拖拽,accept:=true}
Accept := true;
end;
end;
{鼠标释放时执行的语句}
procedure TForm1.Treeview1DragDrop( Sender, Source: TObject;
X, Y : Integer );
var
TempNode : TTreeNode;
AttachMode : TNodeAttachMode;
begin
if Treeview1.Selected = nil then
Exit;
AttachMode := naAddChild; {设置结点移动模式,设移动结点为子结点}
{ 注意在这里存在一个bug,当移动结点时,如果目标结点没有子结点,}
{ 则加入的新的子结点会失败,所以先在当前目标结点的下面 }
{ 加入一个临时子结点,移动完毕后,再将临时结点删除 }
Treeview1.Items.BeginUpdate;
try
TempNode := Treeview1.Items.AddChild( Treeview1.DropTarget,
'Temp' );
try
{ 移动选中的结点到目标结点 }
Treeview1.Selected.MoveTo( Treeview1.DropTarget, AttachMode );
finally
TempNode.Free; { 不要忘了释放临时结点 }
end;
finally
Treeview1.Items.EndUpdate;
end;
end;
比如treeview1.Selected.Text :=edit2.Text ;
至于调用上次的信息,数据库很好实现
或者你把这些信息保存出来比如写到文本里
能不能稍微详细的讲一下用数据库的实现,因为数据量不是很小。
不是说又逐一代码吗?
下面给出第一步:
假设数据表存为111.db,和程序放在同一目录,程序中放TreeView1,memo1,table1,其中table1
的tablename属性为111.db,启动时载入上次退出时的界面的代码如下:
procedure TForm1.FormCreate(Sender: TObject);
var
parentnode: TTreeNode;
begin
table1.Active:=false;
table1.Active:=true;
with table1 do
begin
while not Eof do
begin
if table1.Fields.Fields[1].AsInteger<>-1 then
begin
parentnode:=treeview1.Items.Item[table1.Fields.Fields[1].AsInteger];
Treeview1.Items.AddChild(parentnode,table1.Fields.Fields[0].AsString);
end
else Treeview1.Items.Add(nil,table1.Fields.Fields[0].AsString);
next;
end;
end;
table1.Active:=false;
end;
ABSID PARID LAST CONTENT
0 -1 0 00
1 0 0 11
2 0 1 22
3 2 0 33
4 -1 0 44
5 -1 0 55
6 5 0 66
则说明上次关闭时点击的是第3个节点。程序启动时载入所有节点,并将第3个节点的文本“22”显示在右边的文本框里。刚才给的代码只是显示treeview的,还没加显示文本的,都是你催的,没写完。你先试试这第一步。
procedure TForm1.FormCreate(Sender: TObject);
var
parentnode: TTreeNode;
i:integer;
begin
table1.Active:=false;
table1.Active:=true;
with table1 do
begin
while not Eof do
begin
if table1.Fields.Fields[1].AsInteger<>-1 then
begin
parentnode:=treeview1.Items.Item[table1.Fields.Fields[1].AsInteger];
Treeview1.Items.AddChild(parentnode,table1.Fields.Fields[0].AsString);
end
else Treeview1.Items.Add(nil,table1.Fields.Fields[0].AsString);
if table1.Fields.Fields[2].AsInteger=1 then
begin
memo1.Text:=table1.Fields.Fields[3].AsString;
i:=table1.Fields.Fields[0].AsInteger;
end;
next;
end;
end;
table1.Active:=false;
treeview1.Items.Item[i].Selected:=true;
end;
procedure TForm1.TreeView1Click(Sender: TObject);
begin
if treeview1.Selected.AbsoluteIndex<>-1 then
begin
table1.Active:=false;
table1.Active:=true;
table1.RecNo:=treeview1.Selected.AbsoluteIndex+1;
memo1.Text:=table1.Fields.Fields[3].AsString;
table1.Active:=false;
end;
end;
procedure TForm1.TreeView1Click(Sender: TObject);
begin
try
table1.Active:=false;
table1.Active:=true;
table1.RecNo:=treeview1.Selected.AbsoluteIndex+1;
memo1.Text:=table1.Fields.Fields[3].AsString;
table1.Active:=false;
except
end;
end;
大好人啊:)期待着你将要贴出来的内容!
完成后,另开帖子再给你分:)
点击添加,将此时所点击的节点的绝对节点数赋值给一个变量a,并统计这个节点的所有子节点数目,赋值给另一个变量b,并且弹出一个新的窗口,要求输入添加的内容。点确定以后,在111.db中第a+b+2行添加一行数据(因为a是从0开始增加的),这个所添加的数据内容是:ABSID为a+b+1,PARID为a,LAST为1,CONTENT为新窗口中输入的内容。另外,需要把以前LAST为1的数据赋值为0,并且ABSID大于a+b的数据的ABSID都加1。好象就这么多,可能还有的没写上,慢慢去琢磨了。删除原理和这个差不多,反正主要就是围绕着数据表的ABSID和PARID字段进行修改。LAST和CONTENT一般倒不用操心。第4步在右边修改文本并保存更加容易了,不用我来多说大家都知道怎么做的。
这个程序实现的原理其实很简单,就是操作有点复杂,一步都不能想错,梢有差错,出了问题连自己都很难找出问题所在。
Rebeca,如果你在周末之前还没搞定,可以给我来信,[email protected],周末我再抽取时间帮你一把了。不过你不能偷懒,这几天还是得自己思考,自己解决最好。
最后问一个问题,这个分数用来做什么的?没有分有问题我也会帮忙的,大家都会有困难的。
真的很感谢你,我会努力的.
因为以前从来没做过这些东西,所以一定还会有需要你帮忙的地方,先说声谢谢了.
如果我想再单击一个节点后,在右边的memo中显示出相应的111.db中的content的内容?怎样把content取出来?
begin
try
table1.Active:=false;
table1.Active:=true;
table1.RecNo:=treeview1.Selected.AbsoluteIndex+1;
memo1.Text:=table1.Fields.Fields[3].AsString;
table1.Active:=false;
except
end;
end;
上面不是给了吗?第2步的代码。以后有问题来信问我吧,不可能每天都上这来看贴的。