在TreeView中我知道一个节点的值,那么如何删掉其他的节点,只保留这个节点(如果这个节点有父节点或者子节点都应该保留!)。不知我描述的是否清楚,在线!!
解决方案 »
- 关于win2003+IIS6+INTRAWEB 问题? 大侠们指点一二
- Delphi中这些代表什么啊?这是我在一个获取系统托盘图标的程序中看到的,Shell_TrayWnd, TrayNotifyWnd, SysPager, ToolbarWindow32
- 这段用BDE连接数据库的代码 换成ADO连接的话 应该如何修改?
- 关于图片压缩问题
- 想找个图表插件,但不太熟悉,大家给个建议,谢谢了
- 我用ado+access,现在我想把access数据库备份到某一路经,怎么处理?
- 为什么我用API创建的套接字连接不上TServerSocket?
- Variant 变量的值,如何传递到sstream中。如下例:
- 报表的备注显示?
- 求教多层数据库多表更新的一般做法
- 怎么能让保存到重复记录时,出现出错信息
- 谁知道哪里可以下载支持图文混排的memo或richedit控件???
兄弟能够给点代码?
怎么个判断法?
var
i, j, k,
Node_Count, //根结点的个数
Current_Node_Level,
Next_Node_Level: integer;
Delete_Flag :Boolean; //删除标记
begin
Node_Count := 0;
for i := 0 to TreeView1.Items.Count -1 do
begin
if TreeView1.Items.Item[i].level = 0 then
Inc(Node_Count);
end; if Node_Count = 0 then
begin
ShowMessage('该树没有任何结点!');
Exit;
end; //遍历每一层根结点下的子树,若找不到符合要求的结点便删除该根结点
for i := 1 to Node_Count do
for j := 0 to TreeView1.Items.Count - 1 do
begin
if TreeView1.Items.Item[j].Level = 0 then
begin
k := j;
Delete_Flag := False;
repeat
if TreeView1.Items.Item[k].Text = 'Text' then
begin
Delete_Flag := True;
Break;
end;
if TreeView1.Items.Item[k].getFirstChild = NIL then Break;
Current_Node_Level := TreeView1.Items.Item[k].Level;
Next_Node_Level := TreeView1.Items.Item[k + 1].Level;
Inc(k);
until Next_Node_Level < Current_Node_Level;
if not Delete_Flag then TreeView1.Items.Item[j].Delete;
end;
Break;
end;
end;算法有点冗长,有待优化,但还是可以行的通的
兄弟结果不对呀!
不妨将你的代码贴上!谢谢
简单的办法,声明一个TTreeNode的动态数组,然后对整个TTreeView进行遍历,因为你需要保留的节点你是知道的,那么就遍历TTreeView的时候,如果找到这个节点,那么你就可以得到这个节点的所有父亲节点,这样,你这个时候再动态的设定动态数组的Length,然后把每个父亲节点和本身存放到这个动态数组中,然后进行第二次遍历,然后把每个节点和动态数组中存放的节点进行比较,如果相同,就不删除,否则就删除!这个是非常简单的一种方法,速度不是太快,如果节点量很少,少于100个,那么速度还是非常快的!
简单的办法,声明一个TTreeNode的动态数组,然后对整个TTreeView进行遍历,因为你需要保留的节点你是知道的,那么就遍历TTreeView的时候,如果找到这个节点,那么你就可以得到这个节点的所有父亲节点,这样,你这个时候再动态的设定动态数组的Length,然后把每个父亲节点和本身存放到这个动态数组中,然后进行第二次遍历,然后把每个节点和动态数组中存放的节点进行比较,如果相同,就不删除,否则就删除!这个是非常简单的一种方法,速度不是太快,如果节点量很少,少于100个,那么速度还是非常快的!
var
i : Integer;
Node : TTreeNode;
begin
Node := TV.Selected; //你要保留的node
for i := TV.Items.Count - 1 downto 0 do
if not ((TV.Items[i]=node) or (Node.HasAsParent(TV.Items[i]))) then
TV.Items.Delete(TV.Items[i]);
end;
你分析的完全正确!谢谢!
兄弟讲的很有道理,方法我调试了很长时间,结果还是有错,兄弟能否将你的算法贴出来,让我学习学习!
main: TForm 主界面
tvMain: TTreeView 主界面树控件
btnAddNode: TButton 增加节点
btnAddSubNode: TButton 增加子节点
btnDelNode: TButton 删除节点(核心功能)2、完整代码如下
unit MainP;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;type
PMyData=^TMyData;
TMyData=record
ID, //唯一编号
Val, //值
Flag: string; //标志
end;type
TMain = class(TForm)
tvMain: TTreeView;
btnAddNode: TButton;
btnDelNode: TButton;
btnAddSubNode: TButton;
procedure btnAddNodeClick(Sender: TObject);
procedure btnAddSubNodeClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnDelNodeClick(Sender: TObject);
private
{ Private declarations }
NodeValue: integer;
public
{ Public declarations }
function GetNodeID: String;
end;var
Main: TMain;implementation{$R *.DFM}procedure TMain.btnAddNodeClick(Sender: TObject);
var
newNode,curNode: TTreeNode;
ptrData: PMyData;
begin
(*获取父节点,为增加同级节点做好准备*)
curNode := tvMain.Selected;
if curNode <> nil then
curNode := curNode.Parent; (*增加节点*)
ptrData := new(PMyData);
ptrData^.ID := GetNodeID;
ptrData^.Val := ptrData^.ID;
ptrData^.Flag := 'F'; newNode := tvMain.Items.AddChildObject(curNode,ptrData^.Val,ptrData);
end;procedure TMain.btnAddSubNodeClick(Sender: TObject);
var
newNode,curNode: TTreeNode;
ptrData: PMyData;
begin
(*获取父节点,为增加同级节点做好准备*)
curNode := tvMain.Selected; (*增加节点*)
ptrData := new(PMyData);
ptrData^.ID := GetNodeID;
ptrData^.Val := ptrData^.ID;
ptrData^.Flag := 'F'; newNode := tvMain.Items.AddChildObject(curNode,ptrData^.Val,ptrData);
end;procedure TMain.FormCreate(Sender: TObject);
begin
NodeValue := 1;
end;function TMain.GetNodeID: String;
begin
Result := IntToStr(NodeValue);
Inc(NodeValue);
end;procedure TMain.btnDelNodeClick(Sender: TObject);
function FindNode(var tree: TTreeView; NodeValue: String): TTreeNode;
var
i: Integer;
curNode: TTreeNode;
ptrData: PMyData;
begin
Result := Nil;
for i := 0 to tree.Items.Count - 1 do
begin
curNode := tree.Items[i];
ptrData := PMyData(curNode.Data);
if ptrData^.Val = NodeValue then
begin
Result := curNode;
Break;
end;
end;
end; function DeleteNode(var tree: TTreeView; var Node: TTreeNode): Boolean;
var
oldNode: TTreeNode; i: integer;
begin
oldNode := Node; for i := tree.Items.Count - 1 downto 0 do
begin
if Not( (tree.Items[i].ItemId = Node.ItemId) or
(Node.HasAsParent(tree.Items[i])) or
(tree.Items[i].Level > Node.Level)
) then
begin
tree.Items.Delete(tree.Items[i]);
end;
end; tree.Selected := oldNode;
end;var
lsNodeValue: String; curNode: TTreeNode;
begin
lsNodeValue := IntToStr(NodeValue);
if not InputQuery(' 信息:删除节点 ',' 提示:请输入要删除节点的值 ',lsNodeValue) then exit; curNode := FindNode(tvMain,lsNodeValue);
if curNode <> nil then
begin
tvMain.Selected := curNode;
if MessageDlg(' 提示:确定删除该节点吗? ',mtConfirmation,[mbYES,mbNO],0) <> mrYES then exit; DeleteNode(tvMain,curNode);
ShowMessage(' 信息:节点删除完毕! ');
end
else
begin
ShowMessage(' 信息:您输入的节点值不存在! ');
end;
end;end.
正在测试。先谢谢!
兄弟你的方法完全正确!
现在我还有个小小的变化:如果对这个树Treeview我想同时删除的不止一个节点,如果同时删除多个节点,程序应该怎么变化一下!不好意思,再向你讨教!谢谢
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;type
PMyData=^TMyData;
TMyData=record
ID, //唯一编号
Val, //值
Flag: string; //标志
end;type
TMain = class(TForm)
tvMain: TTreeView;
btnAddNode: TButton;
btnDelNode: TButton;
btnAddSubNode: TButton;
btnDelMNode: TButton;
procedure btnAddNodeClick(Sender: TObject);
procedure btnAddSubNodeClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnDelNodeClick(Sender: TObject);
procedure btnDelMNodeClick(Sender: TObject);
private
{ Private declarations }
NodeValue: integer;
public
{ Public declarations }
function GetNodeID: String;
end;
function FindNode(var tree: TTreeView; NodeValue: String): TTreeNode;
function DeleteNode(var tree: TTreeView; var Node: TTreeNode): Boolean;
function DeleteMNode(var tree: TTreeView; var Nodes: array of TTreeNode): Boolean;var
Main: TMain;implementation{$R *.DFM}function FindNode(var tree: TTreeView; NodeValue: String): TTreeNode;
var
i: Integer;
curNode: TTreeNode;
ptrData: PMyData;
begin
Result := Nil;
for i := 0 to tree.Items.Count - 1 do
begin
curNode := tree.Items[i];
ptrData := PMyData(curNode.Data);
if ptrData^.Val = NodeValue then
begin
Result := curNode;
Break;
end;
end;
end;function DeleteNode(var tree: TTreeView; var Node: TTreeNode): Boolean;
var
oldNode: TTreeNode; i: integer;
begin
oldNode := Node; for i := tree.Items.Count - 1 downto 0 do
begin
if Not( (tree.Items[i].ItemId = Node.ItemId) or
(Node.HasAsParent(tree.Items[i])) or
((tree.Items[i].Level > Node.Level) and (tree.Items[i].HasAsParent(Node)))
) then
begin
tree.Items.Delete(tree.Items[i]);
end;
end; tree.Selected := oldNode;
end;function DeleteMNode(var tree: TTreeView; var Nodes: array of TTreeNode): Boolean;
var
i, //循环变量,遍历整个TTreeView
j: integer; //循环变量,遍欲保留动态节点数组 lbFlag, //比较标志
FirstFlag: Boolean; //初次比较标志,为了给lbFlag赋初值
begin (*遍历树目录*)
for i := tree.Items.Count - 1 downto 0 do
begin
(*对某一节点比较时,初始化初次比较标志*)
FirstFlag := True;
(*遍历欲保留动态节点数组*)
for j := Low(Nodes) to High(Nodes) do
begin
(*非空进行比较*)
if Nodes[j] <> nil then
begin
(*初次比较,给lbFlag赋初值*)
if FirstFlag then
begin
FirstFlag := False;
lbFlag :=
(tree.Items[i].ItemId = Nodes[j].ItemId) or
(Nodes[j].HasAsParent(tree.Items[i])) or
( (tree.Items[i].Level > Nodes[j].Level) and
(tree.Items[i].HasAsParent(Nodes[j])) );
end
else
(*非初次比较,进行逻辑值合并*)
begin
lbFlag := lbFlag or
(tree.Items[i].ItemId = Nodes[j].ItemId) or
(Nodes[j].HasAsParent(tree.Items[i])) or
( (tree.Items[i].Level > Nodes[j].Level) and
(tree.Items[i].HasAsParent(Nodes[j])) );
end; end;
end; (*判断删除*)
if (Not lbFlag) and (Not FirstFlag) then
begin
tree.Items.Delete(tree.Items[i]);
end;
end;
end;procedure TMain.btnAddNodeClick(Sender: TObject);
var
newNode,curNode: TTreeNode;
ptrData: PMyData;
begin
(*获取父节点,为增加同级节点做好准备*)
curNode := tvMain.Selected;
if curNode <> nil then
curNode := curNode.Parent; (*增加节点*)
ptrData := new(PMyData);
ptrData^.ID := GetNodeID;
ptrData^.Val := ptrData^.ID;
ptrData^.Flag := 'F'; newNode := tvMain.Items.AddChildObject(curNode,ptrData^.Val,ptrData);
end;procedure TMain.btnAddSubNodeClick(Sender: TObject);
var
newNode,curNode: TTreeNode;
ptrData: PMyData;
begin
(*获取父节点,为增加同级节点做好准备*)
curNode := tvMain.Selected; (*增加节点*)
ptrData := new(PMyData);
ptrData^.ID := GetNodeID;
ptrData^.Val := ptrData^.ID;
ptrData^.Flag := 'F'; newNode := tvMain.Items.AddChildObject(curNode,ptrData^.Val,ptrData);
end;procedure TMain.FormCreate(Sender: TObject);
begin
NodeValue := 1;
end;function TMain.GetNodeID: String;
begin
Result := IntToStr(NodeValue);
Inc(NodeValue);
end;procedure TMain.btnDelNodeClick(Sender: TObject);
var
lsNodeValue: String; curNode: TTreeNode;
begin
lsNodeValue := IntToStr(NodeValue);
if not InputQuery(' 删除节点: ',' 请输入要删除节点的值... ',lsNodeValue) then exit; curNode := FindNode(tvMain,lsNodeValue);
if curNode <> nil then
begin
tvMain.Selected := curNode;
if MessageDlg(' 提示:确定删除该节点吗? ',mtConfirmation,[mbYES,mbNO],0) <> mrYES then exit; DeleteNode(tvMain,curNode);
ShowMessage(' 信息:节点删除完毕! ');
end
else
begin
ShowMessage(' 信息:您输入的节点值不存在! ');
end;
end;procedure TMain.btnDelMNodeClick(Sender: TObject);
var
Nodes: array of TTreeNode; lsNodeValue: String; curNode: TTreeNode;
begin
lsNodeValue := '';
SetLength(Nodes,0);
while InputQuery(' 删除节点: ',' 请输入要删除节点的值... ',lsNodeValue) do
begin
curNode := FindNode(tvMain,lsNodeValue);
if curNode <> nil then
begin
SetLength(Nodes, High(Nodes)+2);
Nodes[High(Nodes)] := curNode;
end;
lsNodeValue := '';
end;
if Length(Nodes) > 0 then
DeleteMNode(tvMain, Nodes);
end;end.