Winforms .NET WinForm列表框项显示旧值,直到重新分配给它自己为止

Winforms .NET WinForm列表框项显示旧值,直到重新分配给它自己为止,winforms,listbox,Winforms,Listbox,我用自己的对象重新定义ToString来填充ListBox控件。当我使用listBox1.AddmyObject添加这些对象时,这些对象显示正确。但是,如果我以后更改了此对象中的某些内容,则列表框中不会显示任何更改。调试显示listBox1.Items中的对象确实发生了更改,但不会反映在屏幕上 有趣的是,如果我将一个特定的列表框项重新分配给它自己,听起来有点奇怪,不是吗?比如: listBox1.Items[0] = listBox1.Items[0] 该行将在屏幕上显示正确的值 这是怎么回事

我用自己的对象重新定义ToString来填充ListBox控件。当我使用listBox1.AddmyObject添加这些对象时,这些对象显示正确。但是,如果我以后更改了此对象中的某些内容,则列表框中不会显示任何更改。调试显示listBox1.Items中的对象确实发生了更改,但不会反映在屏幕上

有趣的是,如果我将一个特定的列表框项重新分配给它自己,听起来有点奇怪,不是吗?比如:

listBox1.Items[0] = listBox1.Items[0]
该行将在屏幕上显示正确的值


这是怎么回事?它与线程有关吗?

您可以使控件无效,强制重新绘制。。。也许

您是否尝试调用列表框上的刷新?我认为问题在于列表框不知道您的对象已更改。重新指定该项有效的原因是,当集合更改时,列表框将重新绘制自身。

由于您使用对象的ToString来提供列表框项的文本,列表框不知道该值已更改。您应该做的是让对象公开一个公共属性,如Name或Text,并返回您通常从ToString返回的内容

然后将列表框的名称设置为新属性的名称

确保在对象中正确引发PropertyChanged事件,并且列表框应该能够自动拾取更改

编辑:Adrian的编辑提醒我,我相信您需要使用BindingList作为数据源,以便获取属性更改通知。Reflector中的快速扫描看起来像ListBox本身无法获取上述属性更改。但是INotifyPropertyChanged+BindingList应该是这样的。

当列表框第一次显示时,每个项目的ToString值都会被缓存。如果listbox的Items集合中的某个项发生更改,则listbox不会注意到,并且仍然使用缓存的ToString值进行显示。要强制更新列表框,请调用刷新所有项,或调用指定要刷新的项的索引

从刷新项目的MSDN文档:

刷新所有列表框项目并为其检索新字符串


编辑:事实证明这两个方法都是受保护的,因此不能在外部调用。在试图找到解决方案时,我发现这个问题基本上是重复的。

这两个方法都受保护,不打算在外部调用。实际上,刷新只是使控件无效并重新绘制。我怀疑这会对列表框显示的内容产生任何影响。通过在列表框前面拖动一个窗口,然后将其从列表框中拉出,可以实现同样的效果。真正的问题是ListBoxItem正在缓存ToString值,因为没有设置DisplayMember。重复的嘿…这是似曾相识的…在过去的15分钟内,listview/listbox出现了问题。。。。