У меня есть List(T)
, который связан с некоторыми элементами управления, DataGridView только для чтения, ComboBox и несколькими ярлыками. Это прекрасно работает, все элементы управления заполнены правильно, когда загружается форма, все изменения в Label.Text и DataGridView изменяются по мере изменения выбора ComboBox.Обновление контроля привязки данных при изменении данных
Но если я изменяю данные в объекте в Списке, данные, отображаемые в элементах управления, не обновляются, чтобы отражать измененные данные.
Мой класс T
реализует интерфейс INotifyChanged
, а режим обновления привязок данных управления меткой установлен на OnPropertychanged
.
Я могу заставить DataGridView обновить, вызвав его метод Refresh()
, но попытка же для ярлыков кажется неэффективной.
Как я могу внести изменения в данные в объектах моего списка, обновить данные, указанные в элементах управления Label? Я сделал что-то не так?
Мой MRE до сих пор:
Class Form1
' Form1 has a DataGridView, a ComboBox, a Label, a Button and a TextBox
Dim FooList As New List(Of Foo)(3)
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
For Index As Integer = 0 To FooList.Capacity - 1
FooList.Add(New Foo() With {.Bar = Index, .Baz = 0})
Next
' Shows all Bar and Baz
DataGridView1.DataSource = FooList
' User selects Bar value
ComboBox1.DataSource = FooList
ComboBox1.DisplayMember = "Bar"
' Related Baz value shows
Label1.DataBindings.Add(New Binding("Text", FooList, "Baz", DataSourceUpdateMode.OnPropertyChanged))
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
' This is not _actually_ how I'm selecting indexes and changing the data
' But for the MRE it changes the Baz property
'Change the Baz value on the List, should result in Label1 changing
FooList(ComboBox1.SelectedItem.Bar).Baz = TextBox1.Text.Convert.ToUInt16
' Should I even need this when my list objects have INotifyChanged?
DataGridView1.Refresh()
End Sub
End Class
Class Foo
Implements INotifyChanged
Private _bar As UInt16
Private _baz As UInt16
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(ByVal PropertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
End Sub
Property Bar As UInt 16
Get
Return _bar
End Get
Set(value As Byte)
If Not (value = _bar) Then
_bar = Bar
NotifyPropertyChanged("Bar")
End If
End Set
End Property
Property Baz As UInt 16
Get
Return _baz
End Get
Set(value As Byte)
If Not (value = _baz) Then
_baz = Baz
NotifyPropertyChanged("Baz")
End If
End Set
End Property
End Class
Спасибо, используя работу BindingList, хотя мне действительно нужно было создать свой собственный класс, унаследованный BindingList, чтобы я мог добавить некоторые специальные методы List, чтобы уменьшить изменения в текущей кодовой базе. WRT 'CallerMemberName' получается, что хотя у меня установлен .Net 4.5, VS2010 использует только до версии 4.0. Я до сих пор считаю глупо, как языковые обновления привязаны к IDE, а не только к версии фреймворка. Grr. – Toby