.NET WinForm ListBox项显示旧值,直到分配给自身

时间:2010-02-17 23:15:44

标签: winforms listbox

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

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

listBox1.Items[0] = listBox1.Items[0]

此行将在屏幕上显示正确的值。

这里发生了什么?它与线程有什么关系吗?

4 个答案:

答案 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)

你可以使控件无效,强制重新绘制...也许..