【问题标题】:listView removing rows and updatinglistView 删除行并更新
【发布时间】:2012-05-16 13:17:53
【问题描述】:

我有一个正在从多个线程更新的 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 作为项目索引(因为项目被删除)还有其他方法可以实现吗?也许通过定位“用户”子项?然后从中获取子项?

【问题讨论】:

    标签: c# listview


    【解决方案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;
    }
    

    【讨论】:

    • 哦,太好了!开始设置标签后,如何在更新功能中选择要更新的标签?
    • 您有两种可能性,要么在标签索引上保持独立的顺序。在这种情况下,您必须告诉线程要处理哪个项目。或者使标签等于线程号。第一个解决方案维护一个具有所有优点的排序集(二进制搜索),第二个将使用更少的代码,但你需要以某种方式确保线程号是唯一的,否则你会遇到冲突。或者,您可以通过在线程上维护自动增量索引来获得混合解决方案:)
    • 不明白我将如何定位 this.listView2.Items[threadNumber].SubItems[1].Text = user;这个用标签代替
    • 您无法直接找到该项目。你必须寻找它。由于标签索引是增量的,因此我会在列表剩余项目上使用 BinarySearch。
    • 我得到:错误:找不到类型或命名空间名称“ListViewDataItem”(您是否缺少 using 指令或程序集引用?)
    【解决方案2】:

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

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

    【讨论】:

    • 我已经将标签实现为我的threadNumber,但是我将如何在更新方法中根据它进行更新?
    【解决方案3】:

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

    【讨论】:

    • 那行不通。考虑一个包含 4 个项目的列表视图。现在考虑第三个线程在第四个线程之前结束。使用参数 3(索引从 0 开始)调用它只会抛出 OutOfRangeException。
    • 我已经用 FindByValue 调用更新了 asnwer,它应该提供正确的行为
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多