这是我上一个问题的延续,我的TreeView有三级:
--小区
--青青家园
--1幢
--101
--201
--2幢
--101
--幻境佳居
--2幢
--201
--5幢
--101
这是一个由小区-楼幢-单元号组成的树,前面都有多选框,我现在要在右边的listview中显示TreeView中选中的用户信息内容,我已经试过好几过遍历树的方法,但是都不行,所以想请教这里的朋友,帮忙给个思路,谢谢!
--小区
--青青家园
--1幢
--101
--201
--2幢
--101
--幻境佳居
--2幢
--201
--5幢
--101
这是一个由小区-楼幢-单元号组成的树,前面都有多选框,我现在要在右边的listview中显示TreeView中选中的用户信息内容,我已经试过好几过遍历树的方法,但是都不行,所以想请教这里的朋友,帮忙给个思路,谢谢!
不是标准,就是你上次发给我的那个TRzCheckView
...
Case Treeview.Selected.Level of
0:SQL....
1:SQl....
2:SQL....
End;
...
不管什么控件,相信Selected.Level都是差不多的
我用的是标准控件
...
Case Treeview.Selected.Level of
0:SQL.Add('WHERE 小区 ='''+TreeView.Selected.Text+'''');
1:SQL.Add('WHERE 家园 ='''+TreeView.Selected.Text+'''');
2:SQL.Add('WHERE 住房 ='''+TreeView.Selected.Text+'''');
End;
...
代码还没写呢,写过几个都不对,删了。我原先的思路是这样的,遍历Treeview,如果选中的是一级也就是小区级的,那么直接到表中查这个小区的记录,然后再查TreeView的下一个小区级Node,如果没选中,那么再查它的下一级楼幢级是否选中,有则根据小区+楼幢查记录到listView中,没有则继续判下一级单元号是否有选中,没有就查下一个单元号,有就根据小区+楼幢+单元号查记录,我觉的这个思路虽然不是最佳,但也不会错,没想到却是在遍历问题上一直没搞定,我试了一种最简单的遍历:for I:=0 to Treeview.Items.Count - 1 do
begin
str := Treeview.Items[i].Text;
n := TreeView.Items[I].Level;
b := TreeView.Items[I].Selected;
end;好象Level和Selected我这样的用法是不对的,因为F8的过程中没想到结果.
我后来又试了一种:
function TForm1.AllOverTreeView(node:TTreenode):TTreenode;
begin
while node<>nil do
begin
if node.HasChildren then
begin
node:=node.getFirstChild;
allovertreeview(node);
node:=node.Parent;
end;
if node.getNextSibling<>nil then
node:=node.getNextSibling
else
exit;
end;
end;
但是我觉的这种在最后一级子节点多的情况下是有问题的,于是我改了一下代码,确实我的方法能把第一个节点的第三级能全部都遍历到,但是这个第三级遍历完却找不到条件回上一级也就是回到楼幢级轮询了。
procedure TForm1.Button1Click(Sender: TObject);
var
i,j:Integer;
begin
i:=self.TreeView1.Items.Count;
for j:=0 to i-1 do
begin
if self.TreeView1.Items.Item[j].Parent=nil then
self.createmenu(self.MainMenu1.Items,self.TreeView1.Items.Item[j]);
end;
end;procedure TForm1.createmenu(mainitem: TMenuItem; tr: TTreeNode);
var
s:string;
newitem:TMenuItem;
i,j:Integer;
begin
s:=tr.Text;
newitem:=TMenuItem.Create(mainitem);
newitem.Caption:=s;
mainitem.Add(newitem);
i:=tr.Count;
if i=0 then
Exit;
for j:=0 to i-1 do
self.createmenu(newitem,tr.Item[j]);
end;
不可以写成3层循环吗? 违码:
For i:=0 to Level[0].Count do
begin
if Checked then
begin
...
For j:=0 to Level[1].Count do
begin
if Checked then
begin
...
For k:=0 to Level[2].Count do
if Checked then ...
end;
end;
end;
end;
我原先就是写成类似于你写的这个代码,但是我到后来发现在最后一级也就level3上循环跳不到level2了,我也换过用递归,但是总没写成一个可以用的
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
Memo1.Clear;
for i:=0 to Treeview.Items.Count-1 do
begin
//if TreeView.Items[i].Checked then //如果你的那个是这种复选框的话
Case TreeView.Items[i].Level of
0:Memo1.Lines.Add(Treeview.Items[i].Text);
1:Memo1.Lines.Add(' '+Treeview.Items[i].Text);
2:Memo1.Lines.Add(' '+Treeview.Items[i].Text);
End;
end;
end;我试了下,这样就可以遍历整个树
procedure TRES_BOM_VIEW_F.cx_TVChange(Sender: TObject; Node: TTreeNode);
begin
inherited;
if (cx_TV.Parent<>nil) and Assigned(cx_TV.Selected) and (cx_TV.Selected.Level=1) and (cxPageControl1.ActivePage=cxTabSheet5) then //機種不同明細
begin
try
RES_LOADING_F:=TRES_LOADING_F.Create(Self);
RES_LOADING_F.Label1.Caption:='正在檢索機種明細數據......';
RES_LOADING_F.Show;
RES_LOADING_F.Update;
Application.ProcessMessages;
adoq_information.Close;
adoq_information.SQL.Text:='SELECT A.PARN_TYP,A.PARN_LITM,B.PARN_DSC,B.CHLD_LITM,B.CHLD_DSC,B.EFT_FROM,B.EFT_TO,B.QYT,B.LOCATOR,B.PIN_NO,B.ECO_NO '+
' FROM RES_BOM_LH A LEFT JOIN (SELECT CHLD_LITM,MAX(PARN_DSC)AS PARN_DSC,MAX(EFT_FROM)AS EFT_FROM,MAX(EFT_TO)AS EFT_TO,MAX(CHLD_DSC)AS CHLD_DSC,MAX(QYT)AS QYT,MAX(LOCATOR)AS LOCATOR,MAX(PIN_NO)AS PIN_NO,MAX(ECO_NO)AS ECO_NO '+
' FROM RES_BOM_LH GROUP BY CHLD_LITM)B ON A.PARN_LITM=B.CHLD_LITM WHERE PARN_TYP='''+ VarToStr(cx_TV.Selected.Text)+''' GROUP BY A.PARN_TYP,A.PARN_LITM,B.PARN_DSC,B.CHLD_LITM,B.CHLD_DSC,B.EFT_FROM,B.EFT_TO,B.QYT,B.LOCATOR,B.PIN_NO,B.ECO_NO ORDER BY A.PARN_LITM';
adoq_information.Open;
cxGrid5DBBandedTableView1Column1.DataBinding.FieldName:='';
cxGrid5DBBandedTableView1Column2.DataBinding.FieldName:='PARN_TYP';
cxGrid5DBBandedTableView1Column3.DataBinding.FieldName:='PARN_DSC';
cxGrid5DBBandedTableView1Column4.DataBinding.FieldName:='PARN_LITM';
cxGrid5DBBandedTableView1Column5.DataBinding.FieldName:='CHLD_DSC';
cxGrid5DBBandedTableView1Column6.DataBinding.FieldName:='EFT_FROM';
cxGrid5DBBandedTableView1Column7.DataBinding.FieldName:='EFT_TO';
cxGrid5DBBandedTableView1Column8.DataBinding.FieldName:='ECO_NO';
cxGrid5DBBandedTableView1Column9.DataBinding.FieldName:='LOCATOR';
cxGrid5DBBandedTableView1Column10.DataBinding.FieldName:='PIN_NO';
cxGrid5DBBandedTableView1Column11.DataBinding.FieldName:='QYT';
Application.ProcessMessages;
finally
RES_LOADING_F.Close;
end;
end; if (cx_TV.Parent<>nil) and Assigned(cx_TV.Selected) and (cxPageControl1.ActivePage=cxTabSheet7) then //IQC異常信息
begin
try
RES_LOADING_F:=TRES_LOADING_F.Create(Self);
RES_LOADING_F.Label1.Caption:='正在檢索相關數據......';
RES_LOADING_F.Show;
RES_LOADING_F.Update;
Application.ProcessMessages;
adoq_linev.Close;
adoq_linev.SQL.Text:='select distinct b.parn_litm,a.* from openquery(svr_iqcjl,''select * from LineHis'') a left join res_bom_lh b on a.cplh=b.parn_litm '+
' where b.parn_litm in (select distinct parn_litm from res_bom_lh union all select distinct chld_litm from res_bom_lh) and cplh='''+ VarToStr(cx_TV.Selected.Text)+''' order by errdate desc';
adoq_linev.Open;
cxGrid7DBBandedTableView1Column1.DataBinding.FieldName:='autoid';
cxGrid7DBBandedTableView1Column2.DataBinding.FieldName:='bh';
cxGrid7DBBandedTableView1Column7.DataBinding.FieldName:='cplh';
cxGrid7DBBandedTableView1Column8.DataBinding.FieldName:='custname';
cxGrid7DBBandedTableView1Column11.DataBinding.FieldName:='linecode';
cxGrid7DBBandedTableView1Column12.DataBinding.FieldName:='errdate';
cxGrid7DBBandedTableView1Column10.DataBinding.FieldName:='errproduct';
cxGrid7DBBandedTableView1Column9.DataBinding.FieldName:='descript';
cxGrid7DBBandedTableView1Column6.DataBinding.FieldName:='yjdc';
cxGrid7DBBandedTableView1Column3.DataBinding.FieldName:='fx';
cxGrid7DBBandedTableView1Column4.DataBinding.FieldName:='errpresent';
cxGrid7DBBandedTableView1Column5.DataBinding.FieldName:='pm';
Application.ProcessMessages;
finally
RES_LOADING_F.Close;
end;
end
else
begin
try
RES_LOADING_F:=TRES_LOADING_F.Create(Self);
RES_LOADING_F.Label1.Caption:='正在檢索相關數據......';
RES_LOADING_F.Show;
RES_LOADING_F.Update;
Application.ProcessMessages;
adoq_linev.Close;
adoq_linev.SQL.Text:='select distinct b.parn_litm,a.* from openquery(svr_iqcjl,''select * from LineHis'') a left join res_bom_lh b on a.lh=b.parn_litm '+
' where b.parn_litm in (select distinct parn_litm from res_bom_lh union all select distinct chld_litm from res_bom_lh) and lh='''+ VarToStr(cx_TV.Selected.Text)+''' order by errdate desc';
adoq_linev.Open;
cxGrid7DBBandedTableView1Column1.DataBinding.FieldName:='autoid';
cxGrid7DBBandedTableView1Column2.DataBinding.FieldName:='bh';
cxGrid7DBBandedTableView1Column7.DataBinding.FieldName:='lh';
cxGrid7DBBandedTableView1Column8.DataBinding.FieldName:='custname';
cxGrid7DBBandedTableView1Column11.DataBinding.FieldName:='linecode';
cxGrid7DBBandedTableView1Column12.DataBinding.FieldName:='errdate';
cxGrid7DBBandedTableView1Column10.DataBinding.FieldName:='errproduct';
cxGrid7DBBandedTableView1Column9.DataBinding.FieldName:='descript';
cxGrid7DBBandedTableView1Column6.DataBinding.FieldName:='yjdc';
cxGrid7DBBandedTableView1Column3.DataBinding.FieldName:='fx';
cxGrid7DBBandedTableView1Column4.DataBinding.FieldName:='errpresent';
cxGrid7DBBandedTableView1Column5.DataBinding.FieldName:='pm';
Application.ProcessMessages;
finally
RES_LOADING_F.Close;
end
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
Memo1.Clear;
for i:=0 to Treeview.Items.Count-1 do
begin
Case TreeView.Items[i].Level of
0:Memo1.Lines.Add(Treeview.Items[i].Text);
1:Memo1.Lines.Add(Treeview.Items[i].Parent.Text+' '+Treeview.Items[i].Text);
2:Memo1.Lines.Add(Treeview.Items[i].Parent.Parent.Text+' '+Treeview.Items[i].Parent.Text+' '+Treeview.Items[i].Text);
End;
end;
end;应该能满足你的需求了,能把三级的条件都取到
不过说实话,效率不咋滴,期待更效率的案子.
1、在TreeView上选择想要查询的用户(这个用户可以根据小区/小区+楼幢/小区+楼幢+单元号从用户信息表中查询出来);
2、点中一个导入用户列表的按钮;
3、ListView中显示满足Treeview中条件的记录
for i:=0 to rztvMainFrm.Items.Count-1 do
begin
if rztvMainFrm.Items[i].Selected then
begin
Case rztvMainFrm.Items[i].Level of
1:ShowMessage(rztvMainFrm.Items[i].Text);
2:ShowMessage(rztvMainFrm.Items[i].Parent.Text+' '+rztvMainFrm.Items[i].Text);
3:ShowMessage(rztvMainFrm.Items[i].Parent.Parent.Text+' '+rztvMainFrm.Items[i].Parent.Text + '' +rztvMainFrm.Items[i].Text);
else
ShowMessage('没有选中');
end;
end;
end;我用这个代码试了,只能得到最后一个选中的内容,前面几个选中的都没有显示
procedure TForm1.Button1Click(Sender: TObject);
var
Node1,Node2,Node3:TTreeNode;
begin
Memo1.Clear;
Node1:=Treeview1.Items.GetFirstNode;
while Node1.getNextSibling<>nil do
begin
Node2:=Node1.getFirstChild;
while Node2.getNextSibling<>nil do
begin
Node3:=Node2.getFirstChild;
Memo1.Lines.Add(Node3.Text);
while Node3.getNextSibling<>nil do
begin
Memo1.Lines.Add(Node3.Text);
Node3:=Node3.getNextSibling;
end;
Node2:=Node2.getNextSibling;
end;
Node1:=Node1.getNextSibling;
end;
end;
实现你要的全遍历.
复选框的判断是用Selected? //Selected 是判断是否为当前焦点的吧
不是Checked?
while Node3.getNextSibling<>nil do
begin
Node3:=Node3.getNextSibling;
Memo1.Lines.Add(Node3.Text);
end;
我之前代码第三级循环里操作写反了
var
Node, Node1: TTreeNode;
begin
//得到首节点
Node := rztvMainFrm.Items.GetFirstNode;
//得到小区的首节点
Node := Node.getFirstChild;
while Node <> nil do
begin
Node := Node.GetFirstChild; //楼幢
//判
while Node <> nil do
begin
if Node.HasChildren then
begin
Node := Node.getFirstChild;
//以下读单元号
while Node.getNextSibling <> nil do
Node := Node.getNextSibling;
end;
Node := Node.Parent;
Node1 := Node; //保存上一个楼幢Node
Node := Node.getNextSibling;
end;
Node := Node1; Node := Node.Parent;
Node := Node.getNextSibling;
end;
end;我用上面的代码实现了我所需要的遍历
像TCheckBox,它的判断就是CheckBox.Checked
其他很多类似都是用Checked,而不是Selected.
procedure TMainFrm.ToolButton1Click(Sender: TObject);
var
Node, Node1: TTreeNode;
Str: String;
begin
//得到首节点
Node := rztvMainFrm.Items.GetFirstNode; //得到小区的首节点
Node := Node.getFirstChild; //和睦小区
while Node <> nil do
begin
if GetTreeNodeChecked(Node) then
begin
AddUserInfoToListView(Node.Text, '', '', 0); //选中小区级
end else
begin
Node := Node.GetFirstChild;
Node1 := Node;
//1幢
while Node <> nil do
begin
if GetTreeNodeChecked(Node) then
begin
AddUserInfoToListView(Node.Parent.Text,Node.Text, '', 1)
end else
begin
if Node.HasChildren then
begin
Node := Node.getFirstChild;
if GetTreeNodeChecked(Node) then
begin
AddUserInfoToListView(Node.Parent.Parent.Text, Node.Parent.Text, Node.Text, 2);
end; while Node.getNextSibling <> nil do
begin
Node := Node.getNextSibling;
if GetTreeNodeChecked(Node) then
begin
AddUserInfoToListView(Node.Parent.Parent.Text, Node.Parent.Text, Node.Text, 2);
end;
end;
end;
Node := Node.Parent;
Node1 := Node;
end;
Node := Node.getNextSibling;
end;
Node := Node1;
Node := Node.Parent;
end;
Node := Node.getNextSibling;
end;
end;function TMainFrm.GetTreeNodeChecked(Node: TTreeNode): Boolean;
var
vItem : TTVItem;
begin
vItem.mask := TVIF_HANDLE or TVIF_STATE;
vItem.hItem := Node.ItemId;
vItem.stateMask := TVIS_STATEIMAGEMASK;
TreeView_GetItem(Node.TreeView.Handle, vItem);
Result := Boolean((vItem.state shr 12)-1);
end;
procedure TMainFrm.ToolButton1Click(Sender: TObject);
var
Node, Node1: TTreeNode;
Str: String;
begin
//得到首节点
Node := rztvMainFrm.Items.GetFirstNode; //得到小区的首节点
Node := Node.getFirstChild; //和睦小区
while Node <> nil do
begin
if GetTreeNodeChecked(Node) then
begin
AddUserInfoToListView(Node.Text, '', '', 0); //选中小区级
end else
begin
Node := Node.GetFirstChild;
Node1 := Node;
//1幢
while Node <> nil do
begin
if GetTreeNodeChecked(Node) then
begin
AddUserInfoToListView(Node.Parent.Text,Node.Text, '', 1)
end else
begin
if Node.HasChildren then
begin
Node := Node.getFirstChild;
if GetTreeNodeChecked(Node) then
begin
AddUserInfoToListView(Node.Parent.Parent.Text, Node.Parent.Text, Node.Text, 2);
end; while Node.getNextSibling <> nil do
begin
Node := Node.getNextSibling;
if GetTreeNodeChecked(Node) then
begin
AddUserInfoToListView(Node.Parent.Parent.Text, Node.Parent.Text, Node.Text, 2);
end;
end;
end;
Node := Node.Parent;
Node1 := Node;
end;
Node := Node.getNextSibling;
end;
Node := Node1;
Node := Node.Parent;
end;
Node := Node.getNextSibling;
end;
end;function TMainFrm.GetTreeNodeChecked(Node: TTreeNode): Boolean;
var
vItem : TTVItem;
begin
vItem.mask := TVIF_HANDLE or TVIF_STATE;
vItem.hItem := Node.ItemId;
vItem.stateMask := TVIS_STATEIMAGEMASK;
TreeView_GetItem(Node.TreeView.Handle, vItem);
Result := Boolean((vItem.state shr 12)-1);
end;