我有一个BindingList(of T)
,DataSource
是ListBox
。基础类型实现INotifyPropertyChanged
。
添加或删除项目的工作非常出色。它还会立即显示列表中项目的属性更改,但如果在列表框中选择了该项目则不会。
当您尝试更改SelectedItem(或列表中恰好是SelectedItem的项目)时,它会在更改后从控件中消失(DataSource仍然具有它)。我不确定为什么会这样。我不是替换项目,而是替换它上面的属性。样品类型:
Public Class Critter
Implements INotifyPropertyChanged
Private _name As String = ""
Public Property Name As String
Get
Return _name
End Get
Set(value As String)
_name = value
RaiseEvent PropertyChanged(Me,
New PropertyChangedEventArgs("Name"))
End Set
End Property
Public Property Age As Integer
Public Overrides Function ToString() As String
Return String.Format("{0} (Age: {1})", Name, Age.ToString)
End Function
Public Event PropertyChanged(sender As Object,
e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
End Class
代码使用Critters As New BindingList(Of Critter)
,它是ListBox的DataSource。正如我所说,添加和删除工作完美无瑕。选择该项目时,更改Name
失败。使用DisplayMember
而不是ToString
似乎没有什么区别。单击按钮编辑代码:
Dim thisCritter As Critter = Critters(lbCritters.SelectedIndex)
' neither way avoids the result:
'thisCritter = CType(lbCritters.SelectedValue, Critter)
' rename the item
thisCritter.Name = "New Name"
' SelectedItem immediately changes to Nothing in Debug
更简单的是:
Critters(1).Name = "foo"
它可以正常,除非是列表框中的选定/突出显示的项目。因为它似乎与SelectedItem有关,所以它可以工作(它也可以通过Reflection调用RefreshItems
,但不应该这样做):
thisCritter = CType(lbCritters.SelectedItems(0), Critter)
' clear selected items
lbCritters.SelectedItems.Clear()
thisCritter.Name = "New Name"
' reset selection
lbCritters.SelectedItem = thisCritter
那么,编辑SelectedItem时为什么需要这样做?这是一个错误还是我在其他地方做错了什么?
编辑SelectedItem似乎是一个相当常见的用例,但似乎没有任何关于此的内容。这里有很多问题提到BindingList
作为控件没有看到List更改的解决方案,与此问题没什么相似。