为什么 SubItems.Clear() 也会删除 Name 属性?

发布于 2024-09-30 07:33:47 字数 649 浏览 2 评论 0原文

我在详细信息模式下使用 WinForms ListView(.NET 4.0,在 Windows 7 上运行),并且我有一个需要清除特定项目中的子项目的功能。不幸的是,当我这样做时,它的名称也很清楚:

item.Name = "TESTNAME";
item.SubItems.Clear();
MessageBox.Show(item.Name); //shows nothing

在调试器中,我已经追踪到了这个,并且我查看了 MSDN 上的文档 没有帮助,

清除:从集合中删除所有子项和父 ListViewItem。

除了 ListViewItem 仍然非常在那里,因为稍后在函数中我可以再次向其中添加子项!

当然我不必:

while(item.SubItems.Count > 0)
{
    item.RemoveAt(0);
}

是吗?

I am using a WinForms ListView in details mode (.NET 4.0, running on Windows 7) and I have a function that needs to clear the subitems in a particular item. Unfortunately when I do that it also clear's the name:

item.Name = "TESTNAME";
item.SubItems.Clear();
MessageBox.Show(item.Name); //shows nothing

In the debugger I've tracked it down to this, and I've looked at the documentation on MSDN and it's unhelpful,

Clear: Removes all subitems and the parent ListViewItem from the collection.

Except the ListViewItem is still very there because later in the function I'm able to add SubItems to it again!

Surely I don't have to:

while(item.SubItems.Count > 0)
{
    item.RemoveAt(0);
}

Do I?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝海似她心 2024-10-07 07:33:47

不幸的是 ListView 是一头奇怪的野兽,它的一个奇怪的角落是它的项目只是要显示的值的集合,每一列一个。

Name 属性只是自动将某些内容放入第一列中,不幸的是,这个“内容”存在于 SubItems 集合中。

这意味着,如果您检查 SubItems 集合,您会注意到它已经有一个元素,并且在设置该项目的名称后,您将看到该项目的文本等于该元素姓名。

这是 < 的代码code>ListViewItem.Name 属性

public string Name {
    get {
        if (SubItemCount == 0) {
            return string.Empty;
        }
        else {
            return subItems[0].Name;
        }
    }
    set {
        SubItems[0].Name = value;
    }
}

以及 ListViewSubItem.Name 属性 如下所示:

public string Name {
    get {
        return (name == null) ? "": name;
    }
    set {
        name = value;
        if (owner != null) {
            owner.UpdateSubItems(-1);
        }
    }
}

因此,清除 SubItems 集合会导致清除以下属性:正如您所发现的,除了从集合中删除所有其他项目之外,还删除了第一个项目。

实际上,发生的情况是集合被清除,但任何在 SubItems 集合为空时查看该集合的尝试都会创建一个包含一项且具有默认属性值的新集合。在上面的示例代码中,读取 SubItems 集合将如果集合尚不存在,则自动将包含一项的集合分配给内部字段。

所以是的,这就是它“运作”的方式。

事实上,要删除除第一个之外的所有子项,您的循环必须是:

while (item.SubItems.Count > 1)
    item.SubItems.RemoveAt(1);

Unfortunately ListView is a strange beast, and one of the strange corners of it is that its items are just a collection of values to be shown, one for each column.

The Name property just automates putting something into the first column, and unfortunately this "something" lives in the SubItems collection.

This means that if you inspect the SubItems collection, you'll notice that it has one element already, and after setting the name of the item, you'll see the text of that item is equal to that name.

This is the code for the ListViewItem.Name property:

public string Name {
    get {
        if (SubItemCount == 0) {
            return string.Empty;
        }
        else {
            return subItems[0].Name;
        }
    }
    set {
        SubItems[0].Name = value;
    }
}

And the ListViewSubItem.Name property looks like this:

public string Name {
    get {
        return (name == null) ? "": name;
    }
    set {
        name = value;
        if (owner != null) {
            owner.UpdateSubItems(-1);
        }
    }
}

So, clearing the SubItems collection has the consequence of clearing the properties of that first item, as you've discovered, in addition to removing every other item from the collection.

Actually, what happens is that the collection is cleared, but any attempt to look at the SubItems collection while it is empty will create a new collection with one item, with default property values. In the above example code, reading the SubItems collection will automagically assign a collection with one item to the internal field, if the collection isn't already there.

So yes, this is how it "works".

In fact, to remove every subitem except the first, your loop would have to be:

while (item.SubItems.Count > 1)
    item.SubItems.RemoveAt(1);
梦一生花开无言 2024-10-07 07:33:47

来自 MSDN

注意

第一个子项目
ListViewItem.ListViewSubItemCollection
始终是拥有该项目的
子项目。进行操作时
对于集合中的子项目,请确保
改为引用索引位置 1
0 对第一个进行更改
子项目。

因此,清除子项集合时,也会清除父项的值。

From MSDN:

Note

The first subitem in the
ListViewItem.ListViewSubItemCollection
is always the item that owns the
subitems. When performing operations
on subitems in the collection, be sure
to reference index position 1 instead
of 0 to make changes to the first
subitem.

Thus, clearing the sub items collection, clears the values for the parent as well.

短暂陪伴 2024-10-07 07:33:47

请注意1:
ListViewItem.Text(不是Name)是ListViewItem.SubItems[0]但是:
ListViewItem.SubItems.Clear() 还清除 ListViewItem.Name

因此,如果您使用 SubItems.Clear,然后您必须恢复 NameText (如果需要的话)。

请注意2:
如果您使用 *Key 方法(例如 ListView.Items.ContainsKey()ListView.Items.RemoveByKey())来访问项目(而不是 *Index ),请注意 ListViewItem.Name,它是您需要传递给这些方法的 key。多么

聪明的逻辑...

对于任何人被迫或想要使用 ListView 的情况,我发现了 问题 23007388

由于确定所有这些内容可能需要很长时间,因此即使该线程有点旧,我也发布了此答案。

Please note 1:
The ListViewItem.Text (not the Name) is the ListViewItem.SubItems[0], but:
the ListViewItem.SubItems.Clear() clears also the ListViewItem.Name!

So, if you use SubItems.Clear, you then have to restore both Name and Text (if you need them).

Please note 2:
If you use *Key methods (eg. ListView.Items.ContainsKey() or ListView.Items.RemoveByKey()) to access the items (instead of *Index ones), take care of the ListViewItem.Name, which is the key you need to pass to these methods...

What a smart logic...

For the case anyone is forced or wants to use ListView I have discovered another problem described in question 23007388.

As it might take very long time to determine all this stuff, I have posted this answer even this thread is a little bit old.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文