我正在向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项创建一个唯一的索引。
我怎么能做到这一点?
答案 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();