跟踪ListView索引

时间:2012-11-26 19:53:53

标签: c# listview

我正在向ListView添加项目,如下所示:

    private int AddThreadToListView(int threadNumber, string proxy, string query, string page, string links)
    {
        int index = 0;
        listView1.SuspendLayout();

        Invoke(new MethodInvoker(
                       delegate
                       {
                           string[] row1 = { proxy, query, page, links };
                           ListViewItem item = new ListViewItem();

                           listView1.Items.Add(threadNumber.ToString()).SubItems.AddRange(row1);
                           index = listView1.Items.Count - 1;
                       }
                       ));

        if ((listView1.Items.Count % 1000) == 0)
        {
            listView1.ResumeLayout();
            listView1.SuspendLayout();
        }

        listView1.ResumeLayout();
        return index;
    }

然后我跟踪项目索引,以便我可以返回并从我的线程中更新它。 (效果很好)。

问题是当我开始删除这些项目时,由于某些原因索引会发生变化..

以下是我的更新和删除方法:

    private void UpdateThreadListView(int threadNumber, string proxy, string query, string page, string links)
    {
        Invoke(new MethodInvoker(
                       delegate
                       {
                           listView1.BeginUpdate();

                           ListViewItem itm = listView1.Items[threadNumber];
                           itm.SubItems[1].Text = proxy;

                           itm.SubItems[2].Text = query;
                           itm.SubItems[3].Text = page;
                           itm.SubItems[4].Text = links;                               

                           listView1.EndUpdate();

                       }
                       ));
    }

    private void RemoveThreadListView(int threadNumber)
    {
        Invoke(new MethodInvoker(
                       delegate
                       {
                           listView1.BeginUpdate();
                           listView1.Items[threadNumber].Remove();
                           listView1.EndUpdate();

                       }
                       ));
    }

我不知何故需要一个不会改变的索引,每个listview项创建一个唯一的索引。

我怎么能做到这一点?

3 个答案:

答案 0 :(得分:1)

自动管理Index;它表示列表中给定项目的位置,因此如果删除项目,则所有后续项目的位置都将更改。

您可以使用Tag的{​​{1}}属性作为关键字,使用其他条件搜索项目; e.g。

ListViewItem

private ListViewItem FindItem(object myTag) { foreach(ListViewItem myItem in listView1.Items) { if (myItem.Tag.Equals(myTag)) return myItem; } return null; } 可以设置为您想要的任何对象;它主要是出于这个目的(通过索引以外的方式唯一地识别节点)。

请注意,这比使用索引查找元素效率低,因为它是最坏情况Tag(而不是O(n)用于索引)。

编辑:

上述方法只是如何查找给定标签的项目的示例。您可以随时设置标记,但通常您可能希望在创建列表视图项时设置它,例如

O(1)

然后,假设你实现了一个 Invoke(new MethodInvoker( delegate { string[] row1 = { proxy, query, page, links }; ListViewItem item = listView1.Items.Add(threadNumber.ToString()); item.SubItems.AddRange(row1); item.Tag = threadNumber.ToString(); // or whatever you want to search by index = listView1.Items.Count - 1; } )); ,就像我给出了一个上面的例子,你可以这样做:

FindItem()

在此示例中将返回线程#3的项目。

答案 1 :(得分:0)

将int threadNumber复制到本地int

 private void UpdateThreadListView(int threadNumber, string proxy, string query, string page, string links)
    {
        int index = threadNumber;
        Invoke(new MethodInvoker(
                       delegate
                       {
                           listView1.BeginUpdate();

                           ListViewItem itm = listView1.Items[index];
etc..

试图找出原因是什么......

答案 2 :(得分:0)

ListViewItems的索引更改的事实是ListView的正确行为,因为索引只是它在UI控件中的位置。

但是,如果您想跟踪该项目,我建议您不要跟踪索引。相反,跟踪ListViewItem本身。

您现在可以直接操作ListViewItem,直接引用它。刷新ListView后,您应该看到对该项目所做的任何更改。

这是一个简单的例子,可以引导您朝着正确的方向前进。假设我有一个包含3行的ListView,并且我希望在第二行被删除后更新最后一项。

//Grab a reference to the item that I want to update
ListViewItem lvi = this.lvwData.Items[2];

//Remove the second row
this.lvwData.Items.RemoveAt[1];

//Update the ListViewItem
lvi.Text = "Updated";

//Refresh the ListView
this.lvwData.Refresh();