0

我有一个正在从多个线程更新的 listView,其中显示了线程状态和 id。当一个线程结束时,该项目被删除。

我的问题是我用来更新我的 listView 的方式是使用 listViews ID(定位我希望更新的子项)。现在,随着 listView 项目开始被删除,我遇到了问题,因为特定线程的 ID 已更改。

这是我目前用于更新和删除的代码:

    private void AddToListViewThread(string user, string status, int threadNumber)
    {
        Invoke(new MethodInvoker(
                       delegate
                       {
                           listView2.BeginUpdate();
                           this.listView2.Items[threadNumber].SubItems[1].Text = user;
                           this.listView2.Items[threadNumber].SubItems[2].Text = status;
                           listView2.EndUpdate();
                       }
                       ));
    }

    private void RemoveFromListViewThread(int threadNumber)
    {
        Invoke(new 
            MethodInvoker(
                       delegate
                       {
                           listView2.BeginUpdate();
                           this.listView2.Items.RemoveAt(threadNumber);
                           listView2.EndUpdate();
                       }
                       ));
    }

我现在明白我不能使用 threadNumber 作为项目索引(因为项目被删除)还有其他方法可以实现吗?也许通过定位“用户”子项?然后从中获取子项?

4

3 回答 3

1

使用 ListViewItem 的 tag 属性来存储不同的索引(类似于 SQL autoincrement )。

Tag 属性是用于存储有关项目的元数据的字段。

一个简单的二分搜索可以让您在 Log(n) 时间内找到要删除的项目。

您的代码如下所示:

private void AddToListViewThread(string user, string status, int threadNumber)
{
    Invoke(new MethodInvoker(
                   delegate
                   {
                       listView2.BeginUpdate();
                       int i = SearchItem(listView2, threadNumber);
                       if ( i > -1)
                       {
                       this.listView2.Items[i].SubItems[1].Text = user;
                       this.listView2.Items[i].SubItems[2].Text = status;
                       }
                       listView2.EndUpdate();
                   }
                   ));
}

private void RemoveFromListViewThread(int threadNumber)
{
    Invoke(new MethodInvoker(
                   delegate
                   {
                       listView2.BeginUpdate();
                       int i = SearchItem(listView2, threadNumber);
                       if ( i > -1)
                       {
                           this.listView2.Items.RemoveAt(i);
                       }
                       listView2.EndUpdate();
                   }
                   ));
}

private int SearchItem(ListView list, int id)
{ 
         for (int i  = 0; i < list.Items.Count; i++) // I used sequential search but you can implement binary instead
         {
            if (((int)list.Items[i].Tag) == id) return i;
         }
         return -1;
}
于 2012-05-16T13:28:23.670 回答
0

您可能想查看 ListViewItem.Tag 以了解它是否适​​用于您的特定场景。您可以在创建时将线程的 ID 存储在项目的标签中,如果您删除 ListView 中的其他项目,它不会更改。

http://msdn.microsoft.com/en-us/library/system.windows.forms.listviewitem.tag.aspx

于 2012-05-16T13:28:07.287 回答
-1

试试这个->this.listView2.Remove(this.listView2.Items.FindByValue(threadNumber));

于 2012-05-16T13:23:33.560 回答