我有一个树视图和一个列表视图,以及一个应该将所选项目从树视图移动到列表视图的按钮。选择和传输完全正常,但删除树视图中的项目不是。它仅在我在树视图下选择单个项目时才有效。当我有TreeView1.MultiSelect := True
时,就会出现问题。
以下是我正在使用的代码:
For i := 0 to TreeView1.Items.Count-1 do Begin
If TreeView1.Items[i].Selected then
Begin
Itm := ListView1.Items.add;
.....
TreeView1.Items[i].Delete
以上代码在某些选择后给出无效索引。不完美有时只添加两个中的一个。
尝试:
For i := TreeView1.Items.Count to 1 do Begin
当我选择父节点中的所有元素被复制的最后一个元素时,这是无效的代码
for Itr := TreeView1.Items.Count-1 downto 0 do Begin
if TreeView1.Items[Itr].Selected then
begin
Str := TreeView1.Items[Itr].Parent.Text + ' ,' + TreeView1.Items[Itr].Text;
TrimLeft(Str);
for k := 0 to SaveList.Count -1 do Begin
If ansipos(Str, SaveList[k]) > 0 Then Begin
Value := StringReplace(SaveList[k], Str, '',[rfReplaceAll, rfIgnoreCase]);
End;
End;
Itm := ListView1.Items.Add;
Itm.Caption := TreeView1.Items[Itr].Parent.Text;
Itm.SubItems.Add(TreeView1.Items[Itr].Text);
Itm.SubItems.Add(Value);
TreeView1.Items[Itr].Delete
end;
End;
答案 0 :(得分:5)
将for循环更改为:
For i := TreeView1.Items.Count-1 downto 0 do
....
在新代码出现后编辑
你没有显示实际的错误信息,也没有显示它发生在哪一行,但我认为它在这一行
Str := TreeView1.Items[Itr].Parent.Text + ' ,' + TreeView1.Items[Itr].Text;
表示根级别的TreeView项目。那些没有父母的人(IOW Item[itr].Parent
是nil
),结果是Access violation
错误。在尝试访问父项之前,您需要检查项目是否具有父项。
如果您的错误是其他原因,请澄清。
修改,添加了解决方法
正如@MBo报道的那样,原因是删除期间选择会发生变化。为防止这种情况,您可以使用以下解决方法。
在表单中声明一个布尔字段,例如TreeView1_Deleting
,并为树视图声明OnChanging
事件。
type
TForm1 = class(TForm)
TreeView1: TTreeView;
Button1: TButton;
...
procedure TreeView1Changing(Sender: TObject; Node: TTreeNode;
var AllowChange: Boolean);
private
TreeView1_Deleting: boolean;
end;
以及OnChanging
事件的实施:
procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode;
var AllowChange: Boolean);
begin
if TreeView1_Deleting then
AllowChange := False;
end;
最后,在删除所选节点的过程中
begin
TreeView1_Deleting := True; // Add this line
for i := TreeView1.Items.Count-1 downto 0 do
begin
if TreeView1.Items[i].Selected then
begin
// copy values to listview
// and finally delete the node
TreeView1.Items[i].Delete;
end;
end
TreeView1_Deleting := False; // Add this line
end;
记住我之前说过的关于访问根级节点的Parent
属性的内容。
答案 1 :(得分:2)
我可以确认这段代码确实清除了整个分支或所有树(如果选择了最后一个元素)(XE3,Win7 / 32):
for I := TreeView1.Items.Count - 1 downto 0 do begin
if TreeView1.Items[i].Selected then begin
Memo1.Lines.Add(TreeView1.Items[i].Text);
TreeView1.Items[i].Delete;
end;
end;
它将选定的节点标签和父标签输出到根级别 - 因此选择在删除期间跳跃升级(我不会在树视图源中看到原因)
解决方法:标记所选节点,删除选择,删除标记为:
var
i: Integer;
Node: TTreeNode;
begin
for I := TreeView1.SelectionCount - 1 downto 0 do begin
Node := TreeView1.Selections[i];
Memo1.Lines.Add(Node.Text);
Node.Data := Pointer(-1);
end;
TreeView1.Selected := nil;
for I := TreeView1.Items.Count - 1 downto 0 do
if TreeView1.Items[i].Data = Pointer(-1) then
TreeView1.Items[i].Delete;