在循环中从TreeView中删除用户选择的项目时,如何避免无效索引错误? [英] How do I avoid invalid-index errors when removing user-selected items from a TreeView in a loop?

查看:83
本文介绍了在循环中从TreeView中删除用户选择的项目时,如何避免无效索引错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个树形视图和一个列表视图,还有一个按钮,该按钮应将选定的项目从树形视图移动到列表视图.选择和传输进行得非常好,但是不能从树视图中删除项目.仅当我在树视图下选择一个项目时,它才有效.当我有TreeView1.MultiSelect := True时,就出现了问题.

I have a treeview and a listview, and a button that should move selected items from the treeview to the listview. The selection and the transfer are happening perfectly fine, but deleting the items from the treeview is not. It only works if I select a single item under the treeview. When I have TreeView1.MultiSelect := True, then there is a problem.

这是我正在使用的代码:

Here is the code I am using:

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

上面的代码在进行某些选择后给出了无效的索引.有时并不完美,有时只添加其中的两个.

The above code gives an invalid index after certain selection. Not perfect sometimes only one out of two selected are added.

尝试过:

  1. For i := TreeView1.Items.Count to 1 do Begin
  2. 首先填充列表视图,然后尝试从树视图中删除,而不是同时进行.同样的错误.
  3. 试图将父级"和子级"存储在一个数组中,然后在以后使用名称删除它们.问题是没有在树状视图中选择特定项目.

当我选择最后一个元素并复制父节点中的所有元素时,这是不起作用的代码

This is the code which is not working when I select the last element all of the elements in the parent node get copied

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;

推荐答案

将for循环更改为:

For i := TreeView1.Items.Count-1 downto 0 do 
....


在显示新代码后进行编辑


Edit after new code presented

您没有显示实际的错误消息,也没有显示错误消息的发生位置,但我认为它在此行上

You did not show the actual error message, nor on which line it happens, but I assume it is on this line

Str := TreeView1.Items[Itr].Parent.Text + ' ,' + TreeView1.Items[Itr].Text;

表示根目录级别的TreeView项.那些没有父母(IOW Item[itr].Parentnil),结果是Access violation错误.在尝试访问父项之前,您需要检查该项是否具有父项.

for a TreeView item at the root level. Those don't have a parent (IOW Item[itr].Parent is nil) and the result is an Access violation error. You need to check that the item has a parent before attempting to access the parent.

如果您还有其他错误,请澄清.

If your error is something else, please clarify.

编辑,添加了解决方法

如@MBo所述,其原因是选择在删除过程中发生了变化.为防止这种情况,可以使用以下解决方法.

As @MBo reported, the reason is that the selection changes during deletion. To prevent this, you can use the following workaround.

在表单中声明一个布尔值字段,例如TreeView1_Deleting,并为树视图声明一个OnChanging事件.

Declare a boolean field, say, TreeView1_Deleting in your form and an OnChanging event for the tree view.

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;

最后,在删除所选节点的过程中

Finally, in the procedure where you delete the selected nodes

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属性的内容.

Remember what I said earlier regarding accessing the Parent property of a root level node.

这篇关于在循环中从TreeView中删除用户选择的项目时,如何避免无效索引错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆