我使用自己的对象重新定义ToString()来填充ListBox控件。当我使用listBox1.Add(myObject)添加这些对象时,对象会正确显示。但是,如果我稍后更改此对象中的某些内容,则列表框中不会显示任何更改。调试显示listBox1.Items中的对象确实已更改,但它未反映在屏幕上。
有趣的是,如果我将一个特定的列表框项目重新分配给它自己(听起来有点奇怪,不是吗?),如:
listBox1.Items[0] = listBox1.Items[0]
此行将在屏幕上显示正确的值。
这里发生了什么?它与线程有什么关系吗?
答案 0 :(得分:3)
由于您使用对象的ToString来提供列表框项的文本,因此ListBox不知道该值已更改。你应该做的是让对象implement INotifyPropertyChanged然后公开一个公共属性,如Name或Text,并返回你通常从ToString()返回的内容。
然后将ListBox的DisplayMember设置为新属性的名称。
确保您正确地在对象中引发PropertyChanged事件,并且ListBox应该能够自动获取更改。
编辑:Adrian的编辑提醒我,我相信您需要使用BindingList作为数据源才能获取属性更改通知。在Reflector中快速扫描看起来像ListBox本身不会拾取上面提到的属性更改。但是INotifyPropertyChanged + BindingList应该。
答案 1 :(得分:2)
首次显示列表框时,将缓存每个项目的ToString()
值。如果列表框的Items
集合中的项目发生更改,则列表框不会注意到并仍然使用缓存的ToString()
值进行显示。要强制列表框更新,请调用RefreshItems()
刷新所有项目,或调用RefreshItem(int)
指定要刷新的项目的索引。
来自RefreshItems()
的MSDN文档:
刷新所有ListBox项并为它们检索新字符串。
编辑:事实证明这两种方法都受到保护,因此无法在外部调用。在尝试找到解决方案时,我遇到this SO question这个问题基本上是重复的。
答案 2 :(得分:0)
您是否尝试过在ListBox上调用Refresh()
?我认为问题是ListBox不知道你的对象发生了变化。重新分配项目的原因是因为ListBox将在集合更改时重新绘制。
答案 3 :(得分:-2)
你可以使控件无效,强制重新绘制...也许..