我在详细模式下使用WinForms ListView(.NET 4.0,在Windows 7上运行),我有一个需要清除特定项目子项的功能。不幸的是,当我这样做时,它也清楚了这个名字:
item.Name = "TESTNAME";
item.SubItems.Clear();
MessageBox.Show(item.Name); //shows nothing
在调试器中我跟踪了它,我看了documentation on MSDN并且没有用,
清除:从集合中删除所有子项和父ListViewItem。
除了ListViewItem仍然非常那里因为稍后在函数中我能够再次添加SubItems!
当然,我没有:
while(item.SubItems.Count > 0)
{
item.RemoveAt(0);
}
我吗?
答案 0 :(得分:4)
不幸的是ListView
是一个奇怪的野兽,其中一个奇怪的角落是它的项目只是要显示的值的集合,每列一个。
Name
属性只是自动将某些内容放入第一列,不幸的是,这个“内容”存在于SubItems
集合中。
这意味着如果您检查SubItems
集合,您会注意到它已经有一个元素,并且在设置项目名称后,您将看到该项目的文本等于名。
这是ListViewItem.Name
property的代码:
public string Name {
get {
if (SubItemCount == 0) {
return string.Empty;
}
else {
return subItems[0].Name;
}
}
set {
SubItems[0].Name = value;
}
}
ListViewSubItem.Name
property看起来像这样:
public string Name {
get {
return (name == null) ? "": name;
}
set {
name = value;
if (owner != null) {
owner.UpdateSubItems(-1);
}
}
}
因此,除了从集合中删除所有其他项目之外,清除SubItems
集合的结果是清除第一项的属性,如您所发现的那样。
实际上,会发生的事情是清除了集合,但是任何在SubItems
集合为空时查看它的尝试都会创建一个带有一个项目的新集合,其默认属性值。在上面的示例代码中,如果该集合尚未存在,则将SubItems
集合automagically assign a collection with one item读取到内部字段。
所以是的,这就是它的“工作原理”。
事实上,要删除除第一个以外的每个子项,您的循环必须是:
while (item.SubItems.Count > 1)
item.SubItems.RemoveAt(1);
答案 1 :(得分:3)
来自MSDN:
注意强>
第一个子项目 ListViewItem.ListViewSubItemCollection 永远是拥有的项目 子项目。执行操作时 在集合中的子项目,请确保 改为引用索引位置1 0表示更改第一个 子项。
因此,清除子项集合也会清除父项的值。
答案 2 :(得分:0)
请注意1:
ListViewItem.Text
(不是Name
)是ListViewItem.SubItems[0]
,但是:
ListViewItem.SubItems.Clear()
也会清除ListViewItem.Name
!
因此,如果您使用SubItems.Clear
,则必须同时恢复Name
和Text
(如果您需要)。
请注意2:
如果您使用*Key
方法(例如。ListView.Items.ContainsKey()
或ListView.Items.RemoveByKey()
)来访问项目(而不是*Index
个),请注意ListViewItem.Name
,是你需要传递给这些方法的key
......
多么聪明的逻辑......
对于任何人被迫或想要使用ListView
的情况,我发现了question 23007388中描述的另一个问题。
由于确定所有这些内容可能需要很长时间,所以我已经发布了这个答案,即使这个帖子有点老了。